在相互并发的Go协程中发生死锁错误

huangapple go评论81阅读模式
英文:

Deadlock Error in Mutually Concurrent Go Routines

问题

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

func Routine1() {
    mutex1.Lock()

    // 做一些事情

    mutex2.Lock()
    mutex3.Lock()
    将整数发送给例程2
    将整数发送给例程3
    *打印一些东西*
    mutex2.Unlock()
    mutex3.Unlock()

    接收整数
    做一些事情

    mutex2.Lock()
    mutex3.Lock()
    将整数发送给例程2
    将整数发送给例程3
    打印一些东西
    mutex2.Unlock()
    mutex3.Unlock()

    做一些事情
    接收整数
    mutex1.Unlock()
    wg.Done()
}

func Routine2() {
    mutex2.Lock()

    // 做一些事情

    mutex1.Lock()
    mutex3.Lock()
    将整数发送给例程1
    将整数发送给例程3
    打印一些东西
    mutex1.Unlock()
    mutex3.Unlock()

    做一些事情
    接收整数

    mutex1.Lock()
    mutex3.Lock()
    将整数发送给例程1
    将整数发送给例程3
    打印一些东西
    mutex1.Unlock()
    mutex3.Unlock()

    做一些事情
    接收整数
    mutex2.Unlock()
    wg.Done()
}

func Routine3() {
    // 与例程1和2相同的结构
}

func main() {
    wg.Add(3)
    go Routine1()
    go Routine2()
    Routine3()
    wg.Wait()
}

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

附加说明:在play.golang.org/p/UL3rj8DJRk的代码中,您可以找到各种打印语句的输出,例如:process [number] sends [int] to process [number] at [time nano seconds]。然而,由于三个并发例程的结果,有时打印语句无法正确执行(意味着没有完整打印,有些内容被另一个打印语句插入,例如process [number] sends [int] to process [number] at process [number])。有人可以帮助我如何处理这个问题吗?

英文:

I have three concurrent go routines like below,

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()
}

This logical code gives deadlock situation every time. Actually, when it runs, just execute print statement of routine 1 (statement between * marks) manytimes (though my print statement is only one) and gives deadlock error. Can anybody inform me what is wrong with the code logic. Thanks.

NB. For more info, code can be found here, http://play.golang.org/p/pW6aXryUaK, where only line number 290 is executing. The original code which contains no error, can be found here play.golang.org/p/UL3rj8DJRk. I just add lock and unlock to them. Thanks.

I want to add another point: in the code of play.golang.org/p/UL3rj8DJRk, you can find outputs of various print statements like this: process [number] sends [int] to process [number] at [time nano seconds]. However, as the result of three concurrent routines, sometimes the print statement is not executing properly (means not printing whole, there is some thing inserted by another print like process [number] sends [int] to process [number] at process [number]). Can any body help me how to manage this ?

答案1

得分: 1

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

可能是由于获取锁的顺序不正确,或者由于使用了未缓冲的Go通道。

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

如果您需要更详细地讨论代码,您可能应该将其发布到golang-nuts

英文:

It is impossible to identify the cause of the deadlock because the code you posted does not contain enough information.

It may be caused by the order in which you are acquiring locks, or it may be caused by usage of unbuffered Go channels.

Until you post complete Go source code, there is no way to answer your question.

If you need to discuss the code in greater length, you probably should post it to golang-nuts.

huangapple
  • 本文由 发表于 2011年12月2日 11:53:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/8351586.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定