15

Go语言之RWMutex

 4 years ago
source link: https://studygolang.com/articles/25528
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

转自“灰子学技术”,原文链接:https://mp.weixin.qq.com/s/0nfjNsFNIrMhYJMf3P-sEw

本篇文章,笔者主要来介绍读写锁的一种Go语言的实现方式RWMutex。

1.基本概念

读写锁: 是计算机程序的并发控制的一种同步机制,也称“共享-互斥锁”、多读者-单写者锁。读操作可并发重入,写操作是互斥的。

主要适用的场景是 :读多写少的业务场景。这种场景下如果每次读写都使用互斥锁那么整个效率就会变得很低。因为只是读的话并不需要互斥锁来锁住数据,只有写操作的时候需要互斥锁,而读写结合的时候,也是需要加锁的,不然的话会导致读的数据不一定是期望的。

对于RWMutex的规则如下:

1、可以随便读,多个goroutine同时读。

2、写的时候,不能读也不能写。

主要有下面四个API构成,读锁RLock,RUnlock,写锁Lock,Unlock。

zuy2aaA.png!web
MRNfm2Q.png!web

2.实例分析

对于读写锁来说,可以拆分成下面四种情况:

1)读事件结束之后,写事件到达。 2)读事件进行的过程中,写事件到达 。 3)写事件完成之后,读事件到达。  4)写事件进行的过程中,读事件到达。5) 只有读的操作。6)只有写的操作。

对于1)和3)来说,读事件和写事件是顺序执行的,不会出现相互影响的问题,我们主要来看下2),4), 5),6)两种情况的例子。

2.1 例子1, 只有读的操作:

u2yARbz.png!web
yqU7NzQ.png!web

结果分析: 通过运行的结果我们可以看出来,多个读操作不需要等到前一个读事件结束了,才去执行下一个读事件, 所以一旦我们在RLock和RUnlock之间修改共享变量num的时候,有两个协程5号和3号会读到相同的数值3。

2.2 例子2, 只有写的操作:

jEbmQ3a.png!web
FRZNziu.png!web

结果分析: 只有写操作的时候,每一次执行的结果num都是递增的,不会出现乱序,这就说明,写锁的加锁和解锁是互斥的,必需一个加锁和解锁结束了,才执行下一次。

2.3 例子3,读事件进行的过程中,写事件到达:

zIfABrj.png!web
MniiMnv.png!web

结果分析: 通过上面的输出结果,我们可以看出写事件的goroutinue在 2号读数据的goroutinue 结束就开始启动了,因为其他的读协程已经用读锁锁住了,所以在这些调用了读锁的这些读协程都释放了读锁之后,写锁才开始从 阻塞中被拿出来重新执行。

2.4 例子4,写事件进行的过程中,读事件到达

bIBnYrZ.png!web
mEJ3Mvm.png!web

结果分析:从结果可以看出,一旦写操作的协程开始加锁,读操作的 读锁 的加锁操作只能在 写锁 释放之后,才会执行。

3.小结:

通过上面的例子,我们可以看出:1)多个读锁可以同时操作 。2)写锁一旦加锁,不管是读操作还是写操作都不能被执行。3)读锁加锁了之后,只要读锁还没有解锁,写操作是不能被执行的。

参看文档:

rwmutex源码:https://golang.org/src/sync/rwmutex.go?s=987:1319#L18

Go RWMutex 源码学习:https://studygolang.com/articles/22356

维基百科- 读写锁 :https://zh.wikipedia.org/wiki/%E8%AF%BB%E5%86%99%E9%94%81

灰子学技术:

e6BNvay.jpg!web

Recommend

  • 102
    • 微信 mp.weixin.qq.com 6 years ago
    • Cache

    区块链开发语言之go语言学习线路指导

    区块链开发语言之go语言学习线路指导

  • 57
    • studygolang.com 5 years ago
    • Cache

    Go语言之slice特性

    1 slice介绍和说明 golang的数据结构也很多,如List,array,map等,但是有个很特别的数据结构是slice,也叫切片。经常看到很多和数组的定义有关的操作是 make([]string, 10)。那么什么是slice呢? 其实slice也算是g...

  • 32

  • 51
    • 微信 mp.weixin.qq.com 5 years ago
    • Cache

    sync.RWMutex - 解决并发读写问题

  • 24

    目录 虽然Go语言提供channel来保证协程的通信,但是某些场景用锁来显示保证协程的安全更清晰易懂。 Go语言中主要有两种锁,互斥锁Mutex和读写锁RWMutex,下面分别介绍一下使用方法,以及出现死锁的常见场景。

  • 40

    01 介绍 Mutex 互斥锁严格锁定读和写,这在读多写少的场景,未免显得有些「浪费」,在 Go 语言中,sync 包中的 RWMutex 类型可以解决这类问...

  • 5
    • www.debuginn.cn 3 years ago
    • Cache

    Go 并发编程之 RWMutex

    友情提示:此篇文章大约需要阅读 8分钟42秒,不足之处请多指教,感谢您的阅读。 订阅本站 Mutex 是用来保证只有一个 goroutine 访问共享资源,在大量的并发场景中...

  • 1
    • wnanbei.github.io 2 years ago
    • Cache

    Go 读写锁 sync.RWMutex

    Go 读写锁 sync.RWMutex 返回 sync.RWMutex 是一个读写锁,在读多写少的场景中,比 Mutex 的并发能力有很大的提升。 读...

  • 0
    • petsta.net 1 year ago
    • Cache

    When to use Go's RWMutex

    The Go programming language has two flavours of mutex that can be used to serialise access to shared state. They are sync.Mutex and

  • 0

    环境:go 1.19.8 在读多写少的情况下,即使一段时间内没有写操作,大量并发的读访问也不得不在Mutex的保护下变成串行访问,这种情况下,使用Mutex,对性能影响比较大。 所以就要区分读写操作。如果某个读操作的g持有了锁,...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK