gpt4 book ai didi

concurrency - 在 RWMutex Unlock 之后两次调用 RWMutex RLock 时 goroutine 阻塞

转载 作者:IT王子 更新时间:2023-10-29 00:52:32 25 4
gpt4 key购买 nike

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.Lock说:

To ensure that the lock eventually becomes available, a blocked Lock call excludes new readers from acquiring the lock.

否则,一系列读取器在前一个读取锁释放之前获得了读取锁,可能会无限期地饿死写入。

这意味着在同一个 goroutine 已经读取锁定的 RWMutex 上调用 RLock 总是不安全的。 (顺便说一句,Lock 在常规互斥量上也是如此,因为 Go 的互斥量不支持递归锁定。)

它不安全的原因是,如果 goroutine 曾经阻止获取第二个读锁(由于写入器被阻止),它永远不会释放第一个读锁。这将导致以后对互斥量的每次锁定调用都将永远阻塞,从而使部分或全部程序陷入死锁。如果所有 goroutine 都被阻塞,Go 只会检测到死锁。

关于concurrency - 在 RWMutex Unlock 之后两次调用 RWMutex RLock 时 goroutine 阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30547916/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com