一尘不染

并发Go例程中的死锁错误

go

我有三个并发的go例程,如下所示,

func Routine1() {
    mutex1.Lock()

    do something

    mutex2.Lock()
    mutex3.Lock()
    send int to routine 2
    send int to routine 3
   * Print Something *
    mutex2.Unlock()
    mutex3.Unlock()

    receive ints
    do something

    mutex2.Lock()
    mutex3.Lock()
    send int to routine 2
    send int to routine 3
    Print Something
    mutex2.Unlock()
    mutex3.Unlock()

    do something
    receive ints
    mutex1.Unlock()
    wg.Done()
}

func Routine2() {
    mutex2.Lock()

    do something

    mutex1.Lock()
    mutex3.Lock()
    send int to routine 1
    send int to routine 3
    Print Something
    mutex1.Unlock()
    mutex3.Unlock()

    do something
    receive ints

    mutex1.Lock()
    mutex3.Lock()
    send int to routine 1
    send int to routine 3
    Print Something
    mutex1.Unlock()
    mutex3.Unlock()

    do something
    receive ints
    mutex2.Unlock()
    wg.Done()
}

func Routine3() {
// same structure as routine 1 & 2
}
func main() {
wg.Add(3)
go Routine1()
go Routine2()
Routine3()
wg.Wait()
}

该逻辑代码每次都会出现死锁情况。实际上,当它运行时,只需多次执行例程1的打印语句(*标记之间的语句)(尽管我的打印语句只有一个)并给出死锁错误。有人可以告诉我代码逻辑有什么问题吗?谢谢。

注意
有关更多信息,请参见http://play.golang.org/p/pW6aXryUaK,此处仅执行行号290。包含错误的原始代码可以在play.golang.org/p/UL3rj8DJRk中找到。我只是向他们添加锁定和解锁。谢谢。

**我想补充一点:在play.golang.org/p/UL3rj8DJRk代码中,您可以找到各种打印语句的输出,如下所示:进程[number]在[时间纳秒]上将[int]发送到[number]到进程[number]
]。
但是,由于这三个并发例程的结果,有时print语句无法正确执行(意味着未完全打印,这是另一张打印插入的东西,例如进程[number]将[int]发送到进程[number]的进程[number]
])。谁能帮我解决这个问题?**


阅读 196

收藏
2020-07-02

共1个答案

一尘不染

由于您发布的代码没有足够的信息,因此无法确定死锁的原因。

这可能是由于您获取锁的顺序引起的,也可能是由于使用了未缓冲的Go通道引起的。

在发布完整的Go源代码之前,您无法回答问题。

如果您需要讨论更长的代码,则可能应该将其发布到golang-nuts上

2020-07-02