Golang中互斥锁和读写互斥锁

news/2024/12/22 14:50:21/

目录

互斥锁

使用互斥锁的示例代码

读写互斥锁

读写互斥锁的示例代码


互斥锁

        在Golang中,互斥锁(Mutex)是一种基本的同步原语,用于实现对共享资源的互斥访问。互斥锁通过在代码中标记临界区来控制对共享资源的访问,从而保证同一时间只有一个 goroutine 可以访问共享资源,避免了并发访问时的数据竞争和不一致性问题。

        互斥锁的主要方法包括两个,分别是 Lock 和 Unlock。Lock 方法用于锁定共享资源,防止其他 goroutine 访问;Unlock 方法则用于解锁共享资源,允许其他 goroutine 访问。一般来说,在使用互斥锁时,需要先通过 Lock 方法锁定共享资源,访问共享资源,然后再通过 Unlock 方法解锁共享资源,让其他 goroutine 可以访问。

使用互斥锁的示例代码

package mainimport ("fmt""sync"
)var count int
var mutex sync.Mutexfunc increment() {mutex.Lock()count++mutex.Unlock()wg.Done()
}func main() {for i := 0; i < 1000; i++ {wg.Add(1)go increment()}wg.Wait()fmt.Println("Final count:", count)
}

在上面的示例代码中,increment函数是一个goroutine,它用来对count变量进行加1操作。在函数执行前通过mutex.Lock()获取互斥锁,在函数执行结束后通过mutex.Unlock()释放互斥锁。这样就保证了同一时刻只有一个goroutine可以访问count变量,从而避免了数据竞争的问题。

需要注意的是,在使用互斥锁时,一定要注意加锁和解锁的位置,否则可能会出现死锁的问题。

读写互斥锁

        Go语言中的读写互斥锁(RWMutex)是一种特殊类型的互斥锁,它允许多个协程同时读取某个共享资源,但在写入时必须互斥,只能有一个协程进行写操作。相比互斥锁,读写互斥锁在高并发读的场景下可以提高并发性能,但在高并发写的场景下仍然存在性能瓶颈。

        读写互斥锁有两个方法:RLock()和RUnlock()。在读取共享资源时,可以调用RLock()方法加读锁,在读取完成后,需要调用RUnlock()方法释放读锁。在写入共享资源时,需要调用Lock()方法加写锁,在写入完成后,需要调用Unlock()方法释放写锁。当有写锁或读写锁时,不能再加读锁或写锁,直到已经释放了所有锁。

读写互斥锁的示例代码

package mainimport ("fmt""sync""time"
)var (value    intrwLock   sync.RWMutexwaitTime time.Duration = 100 * time.Millisecond
)func readValue() {rwLock.RLock()defer rwLock.RUnlock()time.Sleep(waitTime)fmt.Println("Read value:", value)
}func writeValue(val int) {rwLock.Lock()defer rwLock.Unlock()time.Sleep(waitTime)value = valfmt.Println("Write value:", value)
}func main() {// 读操作可以并行执行for i := 0; i < 5; i++ {go readValue()}// 写操作必须等待读操作全部结束后才能执行for i := 0; i < 5; i++ {go writeValue(i)}// 等待所有goroutine执行完毕time.Sleep(time.Second)
}

在这个示例中,使用了一个全局变量value来存储值,使用了一个sync.RWMutex类型的变量rwLock来保护这个变量的读写。在readValue函数中,首先调用RLock方法获取读锁,然后等待一段时间,最后输出变量value的值。在writeValue函数中,首先调用Lock方法获取写锁,然后等待一段时间,将传入的值赋给变量value,最后输出变量value的值。

main函数中,首先启动5个goroutine来执行readValue函数,这些goroutine可以并行执行。然后启动5个goroutine来执行writeValue函数,这些goroutine必须等待所有的读操作完成后才能执行,因为它们需要获取写锁。

需要注意的是,在使用读写互斥锁时,必须保证写操作只有一个,否则就会出现竞争状态,导致数据不一致的问题。同时也需要注意使用锁的力度,避免锁的范围过大,导致性能下降。


http://www.ppmy.cn/news/80733.html

相关文章

LC-3机器码编程实验 求成绩等级

一、实验目的 分析和理解指定的需解决问题。利用LC-3的汇编代码设计实现相关程序。通过LC-3仿真器调试和运行相关程序并得到正确的结果。 二、实验内容 对学生的成绩使用数组进行排序。 背景&#xff1a;一位老师需要你帮忙决定学生的成绩&#xff0c;她想要根据学生分数在…

设计模式-外观模式

目录 介绍 代码演示 屏幕 主机 键盘 电脑组装 ​编辑 外观模式的注意事项和细节外观模式的注意事项和细节 介绍 1&#xff09;外观模式&#xff08;Facade)&#xff0c;也叫“过程模式:外观模式为子系统中的一组接口提供 一个一致的界面&#xff0c;此模式定义了一个高层…

2023年美国大学生数学建模竞赛D题联合国可持续发展目标的优先次序解题全过程文档及程序

2023年美国大学生数学建模竞赛 D题 联合国可持续发展目标的优先次序 原题再现&#xff1a; 背景   联合国(UN)制定了17 项可持续发展目标(SDGs)。实现这些目标将最终改善世界各地许多人的生活。这些目标不是相互独立的。因此&#xff0c;在某些目标上的积极收获通常会对其他…

小白眼中的卷积神经网络(CNN)

相信和笔者一样爱技术对AI兴趣浓厚的小伙伴们&#xff0c;一定对卷积神经网络并不陌生&#xff0c;也一定曾经对如此“高级”的名字困惑良久。今天让我们一起回顾/学习这玩意到底是什么和为什么呢。 引言 说起CNN&#xff0c;必然会首先想到的是CV吧&#xff0c;而边缘检测可…

GPT前2代版本简介

承接上文ChatGPT进化的过程简介 2018年&#xff0c;Google的Bert和OpenAI的GPT绝代双骄&#xff0c;两者非常像&#xff0c;都是语言模型&#xff0c;都基本上是无监督的方式去训练的&#xff0c;你给我一个文本&#xff0c;我给你一个语言模型出来。 GPT前两代没有什么特别的…

《JavaEE》HTTPS

文章目录 HTTPS起源HTTPS对称加密非对称加密两者的区别 HTTPS的安全问题使用对称加密正常交互黑客入侵解决方案 非对称加密引入非对称加密后的流程 中间人攻击黑客的入侵方案加入后的流程解决方案黑客再次加注解决方案 ​&#x1f451;作者主页&#xff1a;Java冰激凌 &#x1…

Java StringBuilder类

3 StringBuilder可变字符串类 StringBuilder是一个可变的字符串类,内容可以改变3.1 StringBuilder构造方法 范例public class Demo {public static void main(String[] args) {//创建空白可

ChatGPT是什么

什么是ChatGPT ChatGPT是一种基于人工智能技术的聊天机器人&#xff0c;它可以与用户进行自然语言交互&#xff0c;回答用户的问题&#xff0c;提供各种服务和娱乐功能。ChatGPT的核心技术是GPT&#xff08;Generative Pre-trained Transformer&#xff09;&#xff0c;是一种…