登录
首页 >  Golang >  Go问答

检测在同一 Goroutine 中连续调用两次 sync.Mutex.Lock()

来源:stackoverflow

时间:2024-02-29 15:45:25 148浏览 收藏

今日不肯埋头,明日何以抬头!每日一句努力自己的话哈哈~哈喽,今天我将给大家带来一篇《检测在同一 Goroutine 中连续调用两次 sync.Mutex.Lock()》,主要内容是讲解等等,感兴趣的朋友可以收藏或者有更好的建议在评论提出,我都会认真看的!大家一起进步,一起学习!

问题内容

这段代码(单线程程序)永远不会工作:

func TestDoubleLockPanics(t *testing.T) {
    var mu sync.Mutex
    mu.Lock()
    mu.Lock()
}

但是,当我运行此测试时,并没有出现恐慌。竞争检测器不会打印出数据竞争。 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 ...
}

在这种情况下,我们不希望 f 的第二个 lock 调用出现恐慌。

你可以构建自己的递归锁或者其他技术,但是由于每个goroutine的内部id是隐藏的,所以它是pretty tricky。在this answerRecursive locking in Go的注释中有一个an implementation的链接,但我从来没有使用过它,或者甚至还仔细观察过。

终于介绍完啦!小伙伴们,这篇关于《检测在同一 Goroutine 中连续调用两次 sync.Mutex.Lock()》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>