吾日三省吾身:高否?富否?帅否?是,滚回家;否,滚去学习
- 前言
上篇文章我们聊了下chan是如何解决不满足HappensBefore条件的goroutine的,接下来这篇文章我们继续来聊聊 锁 是怎么满足这个HappensBefore的。
- 例子
还是上篇文章销毁goroutine的例子
package main
var a string
func hello() {
go func() { a = "hello" }()
print(a)
}
func main() {
hello()
}
我们说这个例子有问题,上篇文章说了,就是结果不确定,那么我们如何通过锁来解决呢?
- 解决
sync包实现了两个锁的数据类型sync.Mutex和sync.RWMutex。
对任意的sync.Mutex或sync.RWMutex变量l和n < m,n次调用l.Unlock()先行发生于m次l.Lock()返回。
package main
import "sync"
var a string
var l sync.Mutex
func hello() {
l.Lock() //先加锁
go func() {
a = "hello"
l.Unlock() //在释放锁
}()
l.Lock() //再加锁的时候发现锁还没释放呢,所以等待,这个时候一定是a的w先执行,后面print(a)即a的r后执行,这就满足HappensBefore了
print(a)
}
func main() {
hello()
}
能保证打印出"hello"。第一次调用l.Unlock()先行发生于第二次l.Lock()返回, 先行发生于print,即a的w发生于a的r之前。
- 小结
对于sync.RWMutex变量l,任意的函数调用l.RLock满足第n次l.RLock后发生于第n次调用l.Unlock,对应的l.RUnlock先行发生于第n+1次调用l.Lock。大家不妨自己试着写下这个demo。
- 关注公众号
微信公众号: 堆栈future