Go 语言中的锁

这篇具有很好参考价值的文章主要介绍了Go 语言中的锁。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 并发基础

并发是同时发生多个计算或事件的能力。并发通常通过同时执行多个任务或进程来实现,这些任务或进程共享相同的资源(例如内存或处理器)。并发使用的基本机制被称为锁。在Go语言中,锁是一个类型变量,它包含一个内部计数器,用于跟踪已获取的锁的数量。当一个goroutine获取一个锁时,它会将计数器增加一;当一个goroutine释放一个锁时,它会将计数器减少一。

2. 锁类型

Go语言中提供了五种类型的锁:互斥锁(mutex)、读写锁(RWMutex)、等待组(WaitGroup)、一次性锁(Once)和条件变量(Cond)。文章来源地址https://www.toymoban.com/news/detail-795495.html

  • 互斥锁(mutex)是一个基础的锁,它只能被一个goroutine同时持有。如果另一个goroutine试图获取一个已被持有的互斥锁,它将被阻塞,直到持有锁的goroutine释放锁。
package main

import (
    "fmt"
    "sync"
)

func main() {
    // 创建一个互斥锁
    var mutex sync.Mutex

    // 使用互斥锁保护共享资源
    mutex.Lock()
    fmt.Println("Only one goroutine can access the shared resource at a time.")
    mutex.Unlock()
}
  • 读写锁(RWmutex)是一种更高级的锁,它允许多个goroutine同时读取受保护的数据,但只允许一个goroutine同时写入受保护的数据。这可以提高程序的性能,因为读取操作通常比写入操作要快。
package main

import (
    "fmt"
    "sync"
)

func main() {
    // 创建一个读写锁
    var rwmutex sync.RWMutex

    // 使用读写锁保护共享资源
    rwmutex.RLock()
    fmt.Println("Multiple goroutines can read the shared resource at the same time.")
    rwmutex.RUnlock()

    // 使用写锁保护共享资源
    rwmutex.Lock()
    fmt.Println("Only one goroutine can write to the shared resource at a time.")
    rwmutex.Unlock()
}
  • 等待组(WaitGroup)是一个同步原语,它允许一个goroutine等待其他一组goroutine完成。
package main

import (
    "sync"
    "fmt"
)

var wg sync.WaitGroup

func main() {
    // 创建10个goroutine来并发地执行任务
    for i := 0; i < 10; i++ {
        wg.Add(1) // 告诉等待组有1个goroutine需要等待
        go func() {
            // 执行任务
            fmt.Println("Hello, world!")
            wg.Done() // 告诉等待组当前goroutine已完成
        }()
    }

    // 等待所有goroutine完成
    wg.Wait()

    fmt.Println("All goroutines have finished.")
}
  • 一次性锁(Once)是一个同步原语,它确保某个操作只被执行一次。
package main

import (
    "sync"
    "fmt"
)

var once sync.Once

func main() {
    // 只执行一次init函数
    once.Do(func() {
        fmt.Println("Hello, world!")
    })
}
  • 条件变量(Cond)是一种同步原语,它允许一个goroutine等待某个条件满足。
package main

import (
    "sync"
    "fmt"
    "time"
)

var cond = sync.NewCond(&sync.Mutex{})
var count int

func main() {
    go func() {
        // 等待count大于0
        cond.L.Lock()
        for count <= 0 {
            cond.Wait()
        }
        cond.L.Unlock()

        fmt.Println("Count is greater than 0.")
    }()

    // 将count设置为1,并通知等待的goroutine
    time.Sleep(1 * time.Second)
    cond.L.Lock()
    count = 1
    cond.Signal()
    cond.L.Unlock()
}

3.锁的注意事项

  • 死锁:死锁是指两个或多个goroutine相互等待对方释放锁,从而导致程序永远无法继续执行。为了避免死锁,必须确保每个goroutine在释放一个锁之前都必须获取该锁。
  • 锁争用:锁争用是指多个goroutine同时尝试获取同一个锁,从而导致程序性能下降。为了减少锁争用,可以尽量使用读写锁,并减少锁的持有时间。
  • 锁粒度:锁粒度是指锁保护的资源的范围。锁粒度越小,对程序并发性的影响就越小。因此,在选择锁的类型和粒度时,应权衡锁的性能和并发性。

到了这里,关于Go 语言中的锁的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Golang星辰图】数据管理利器:Go编程语言中的数据库和搜索引擎综合指南

    Go编程语言是一种强大、类型安全且高效的编程语言,它在处理数据库和搜索引擎方面有着广泛的应用。本篇文章将详细介绍几个Go编程语言中常用的数据库和全文搜索引擎,包括Go-bleve、Go-pgx、Go-leveldb/leveldb、Go-xorm、Go-mysql-driver和Go-bbolt/bbolt。对于每个工具,我们将介绍其功

    2024年03月26日
    浏览(72)
  • 100天精通Golang(基础入门篇)——第12天:深入解析Go语言中的集合(Map)及常用函数应用

    🌷 博主 libin9iOak带您 Go to Golang Language.✨ 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批

    2024年02月12日
    浏览(50)
  • Golang:Go语言结构

    在我们开始学习 Go 编程语言的基础构建模块前,让我们先来了解 Go 语言最简单程序的结构。 Go 语言的基础组成有以下几个部分: 包声明 引入包 函数 变量 语句 表达式 注释 接下来让我们来看下简单的代码,该代码输出了\\\"Hello World!\\\": 让我们来看下以上程序的各个部分: 第一

    2024年02月10日
    浏览(59)
  • golang实现webgis后端开发

    目录 前言 二、实现步骤 1.postgis数据库和model的绑定 2.将pg库中的要素转换为geojson (1)几何定义 (2)将wkb解析为几何类型 (3)定义geojson类型 (4)数据转换 (5)数据返回  2.前端传入的geojson储存到数据库 3、其他功能实现 总结         停更了接近一个月都在研究一门新语言gola

    2024年02月08日
    浏览(50)
  • 【Golang中的Go Module使用】

    Golang中的Go Module是一个用于包管理和版本控制的工具。在本文中,我们将深入探讨Go Module的相关知识,包括其定义、使用方法以及一些常见的应用场景。 Go Module是Golang中的包管理和版本控制工具,它的发展历程、用法、意义以及相关指令都对于Golang开发者来说非常重要。在本

    2024年02月16日
    浏览(47)
  • 【GoLang】MAC安装Go语言环境

    小试牛刀 首先安装VScode软件 或者pycharm mac安装brew软件  brew install go 报了一个错误 不提供这个支持  重新brew install go 之后又重新brew reinstall go 使用go version 可以看到go 的版本 使用go env  可以看到go安装后的配置 配置一个环境变量 vim ~/.zshrc,  

    2024年02月15日
    浏览(60)
  • 【Golang】VScode配置Go语言环境

    安装VScode请参考我的上一篇博客:VScode安装_㫪548的博客-CSDN博客 接下来我们直接进入正题: Go语言(又称Golang)是一种开源的编程语言,由Google开发并于2009年首次发布。Go语言具有简洁、高效、可靠和易于阅读的特点,被设计用于解决大型项目的开发需求。它结合了静态类型

    2024年02月03日
    浏览(66)
  • Go语言(Golang)数据库编程

    要想连接到 SQL 数据库,首先需要加载目标数据库的驱动,驱动里面包含着于该数据库交互的逻辑。 sql.Open() 数据库驱动的名称 数据源名称 得到一个指向 sql.DB 这个 struct 的指针 sql.DB 是用来操作数据库的,它代表了0个或者多个底层连接的池,这些连接由sql 包来维护,sql 包会

    2024年02月03日
    浏览(95)
  • 【Golang】Golang进阶系列教程--Go 语言 map 如何顺序读取?

    Go 语言中的 map 是一种非常强大的数据结构,它允许我们快速地存储和检索键值对。 然而,当我们遍历 map 时,会有一个有趣的现象,那就是输出的键值对顺序是不确定的。 先看一段代码示例: 当我们多执行几次这段代码时,就会发现,输出的顺序是不同的。 首先,Go 语言

    2024年02月14日
    浏览(69)
  • 【Golang】Golang进阶系列教程--Go 语言数组和切片的区别

    在 Go 语言中,数组和切片看起来很像,但其实它们又有很多的不同之处,这篇文章就来说说它们到底有哪些不同。 数组和切片是两个常用的数据结构。它们都可以用于存储一组相同类型的元素,但在底层实现和使用方式上存在一些重要的区别。 Go 中数组的长度是不可改变的

    2024年02月15日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包