并发Go例程中的死锁错误

时间:2011-12-02 03:53:08

标签: go concurrent-programming goroutine

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

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的print语句(*标记之间的语句)很多次(虽然我的print语句只有一个)并给出死锁错误。任何人都可以告诉我代码逻辑有什么问题。感谢。

NB。有关详细信息,可在此处找到代码http://play.golang.org/p/pW6aXryUaK,其中仅执行第290行。原始代码中没有错误,可以在这里找到play.golang.org/p/UL3rj8DJRk。我只是为他们添加锁定和解锁。感谢。

我想补充一点:在play.golang.org/p/UL3rj8DJRk的代码中,您可以找到各种打印语句的输出,如下所示:process [number] send [int] to process [number ]在[时间纳秒]。但是,由于三个并发例程的结果,有时print语句没有正确执行(意味着不打印整个,有一些东西被另一个打印插入,如process [number]发送[int]到process [number]进程[number] ])。任何人都可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

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

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

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

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