登录
首页 >  Golang >  Go问答

无法采用教材中的案例模拟死锁

来源:stackoverflow

时间:2024-03-02 08:30:27 238浏览 收藏

在IT行业这个发展更新速度很快的行业,只有不停止的学习,才不会被行业所淘汰。如果你是Golang学习者,那么本文《无法采用教材中的案例模拟死锁》就很适合你!本篇内容主要包括##content_title##,希望对大家的知识积累有所帮助,助力实战开发!

问题内容

我正在阅读 katherine cox-buday 所著的《go 中的并发:开发人员的工具和技术》,并且被困在一个旨在模拟死锁的非常简单的示例中。该片段看起来像这样。

func main() {
    var wg sync.waitgroup
    printsum := func(a, b *somevar) {
        defer wg.done()
        a.mu.lock()
        defer a.mu.unlock()
        time.sleep(1 * time.second)

        b.mu.lock()
        defer b.mu.unlock()

        fmt.printf("sum is - %d \n", a.val + b.val)
    }

    var a, b somevar
    a.val = 50
    b.val = 300
    wg.add(2)
    go printsum(&a, &b)
    go printsum(&a, &b)
    wg.wait()
}

根据书中描述死锁如何发生的图

但是,当我尝试运行它时,我总是得到输出。

sum is - 352 
sum is - 354

在此示例中,printsum 的第二个实例是等待 var a 上的锁并仅在获取锁时才继续执行,还是继续前进并获取 var b 上的锁? 这本书是 2015 年的,那么语言行为是否发生了导致示例无效的变化?


解决方案


你的实现是错误的。死锁是由循环锁触发的,只有当你以不同的顺序锁定两个锁时才会发生死锁。因此,请执行以下操作:

go printSum(&a, &b)
go printSum(&b, &a)

当锁顺序如上所示时,第一个 printsum 将锁定 a,第二个将锁定 b,然后它们将等待另一个锁释放,这永远不会发生。

以上就是《无法采用教材中的案例模拟死锁》的详细内容,更多关于的资料请关注golang学习网公众号!

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