并发 – 在RWMutex解锁后两次调用RWMutex RLock时的goroutine块
var mu sync.RWMutex go func() { mu.RLock() defer mu.RUnlock() mu.RLock() // In my real scenario this second lock happened in a nested function. defer mu.RUnlock() // More code. }() mu.Lock() mu.Unlock() // The goroutine above still hangs. 如果函数读取/写入互斥锁两次,而另一个函数写入锁定然后写入 – 解锁相同的互斥锁,则原始函数仍会挂起. 这是为什么?是因为有一个连续顺序,其中互斥体允许代码执行? 我刚刚通过删除第二个mu.RLock()行解决了这样的场景(花了我几个小时精确定位). 解决方法
这是读写锁的几种标准行为之一.什么
Wikipedia calls “Write-preferring RW locks”.
同步的文档
否则,一系列读者在上一次发布之前就已经获得了读锁定,它可能会无限期地挨饿. 这意味着在RWMutex上调用RLock始终是不安全的,因为相同的goroutine已经读取了锁定. (顺便说一句,对常规互斥锁也是如此,因为Go的互斥锁不支持递归锁定.) 它是不安全的原因是,如果goroutine阻止获得第二次读锁(由于被阻止的写入器),它将永远不会释放第一个读锁定.这将导致互斥锁上的每个未来锁定调用永远阻塞,解锁部分或全部程序.如果所有goroutine都被阻止,Go将仅检测到死锁. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |