Kev*_*rke 4 mutex locking go reentrancy
这段代码(单线程程序)永远不会工作:
func TestDoubleLockPanics(t *testing.T) {
var mu sync.Mutex
mu.Lock()
mu.Lock()
}
Run Code Online (Sandbox Code Playgroud)
然而,当我运行这个测试时,并没有恐慌。竞争检测器不会打印出数据竞争。go vet不抱怨,没有日志消息,它只是永远阻塞。
(显然,我关心的实际代码并不是这么简单 - 我只是将其归结为本质。)
当持有锁的线程尝试重新获取相同的锁时,有什么方法可以让 Go 大声告诉我吗?
Go 的sync.Mutex对象不跟踪哪个 goroutine 锁定了它们。或者,换句话说,没有锁定线程:只有数据锁。
此外,正如上面的评论Unlock所说,您可以从锁定它们的 goroutine 之外的其他 goroutine 中解锁它们。因此,调用Lock两次实际上是有意义的。这是一个骨架示例:
func f() {
mu.Lock()
... if this is not just an example, some code goes here ...
// now wait for g() to call mu.Unlock()
mu.Lock()
fmt.Println("we got here, so g() must have done an unlock")
mu.Unlock()
}
func g() {
... some code probably goes here too ...
mu.Unlock() // allow f() to proceed
... more code, perhaps ...
}
Run Code Online (Sandbox Code Playgroud)
f在这种情况下,我们不希望在第二次调用中出现恐慌Lock。
您可以构建自己的递归锁或其他技术,但由于每个 goroutine 的内部 ID 是隐藏的,因此非常棘手。在Recursivelocking in Go的答案的评论中有一个实现的链接,但我从未使用过它,甚至没有仔细研究过它。
| 归档时间: |
|
| 查看次数: |
3854 次 |
| 最近记录: |