写点什么

Golang:并发操作中常见的读写锁

用户头像
Regan Yue
关注
发布于: 2 小时前
Golang:并发操作中常见的读写锁

Golang:并发操作中常见的读写锁

互斥锁简单粗暴,谁拿到谁操作。今天给大家介绍一下读写锁,读写锁比互斥锁略微复杂一些,不过我相信我们今天能够把他拿下!


读写锁有两种模式。没错!一种是读模式,一种是写模式。当他为写模式的话,作用和互斥锁差不多,只允许有一个协程抢到这把锁,其他协程乖乖排队。但是读模式就不一样了,他允许你多个协程读,但是不能写。总结起来就是:


  • 仅读模式: 多协程可读不可写

  • 仅写模式: 单协程可写不可读


在 32 位的操作系统中,针对 int64 类型的值的读和写操作都不可能仅由一个 CPU 指令来完成。如若一个写操作刚刚执行完第一个指令,就去进行另一个读的协程,这样就会读到一个错误的数据。


下面看个例子吧:


先看主函数:


func main() {  for i:=0;i<5;i++{    wg06.Add(1)    go write(i)
wg06.Add(1) go read(i) } wg06.Wait()}
复制代码


每次开辟两条协程,一条协程执行写函数,另一条执行读函数。然后放入等待组。共开辟五次。


在来看一看写函数


func write(i int)  {  //锁定为仅写模式,其他协程被阻塞  rwm.Lock()
fmt.Println(i,"writing...") <- time.After(10*time.Second) fmt.Println("write over!")
rwm.Unlock() //解锁仅写模式 wg06.Done()}
复制代码


这个 Lock()就是执行读写锁的写模式,当这个模式进行时,只有这条协程能写,其他协程都被阻塞。Unlock()就是解锁这个仅锁模式,等待组中的其他协程不再被阻塞。


再看一看读模式:


func read(i int)  {  rwm.RLock()
fmt.Println(i,"reading...") <-time.After(10 * time.Second) fmt.Println(i,"read over!")
rwm.RUnlock() wg06.Done()}
复制代码


RLock()就是执行读写锁的读模式,执行这个模式其他协程也能读,但是都不能写。


如果程序运行,写协程先抢到锁,所有协程就不能读,只有这条写协程能写,其他人都等着。如果是读协程抢到锁,所以写协程就不可能了,但是读协程仍然可以抢。


现在你知道我们应该什么时候使用读写锁了吗?


在并发进行读写操作时,当读的次数远远超过写的次数的情况下,应该使用读写锁来进行读写并发操作。

发布于: 2 小时前阅读数: 4
用户头像

Regan Yue

关注

还未添加个人签名 2020.08.12 加入

对Go、Python、网络安全、区块链感兴趣.

评论

发布
暂无评论
Golang:并发操作中常见的读写锁