初学者级代码死锁

时间:2017-10-14 22:55:36

标签: go concurrency deadlock

这是我的主要功能;

c := make(chan int)

go func() {

    i := <-c
    i++
    time.Sleep(100 * time.Millisecond)

    c <-i


}()

time.Sleep(1 * time.Second)
go func() {
    i := <-c
    i++
    time.Sleep(100 * time.Millisecond)
    c <-i

}()

time.Sleep(1 * time.Second)
fmt.Println(<-c)

我得到了死锁错误。即使我已经尝试过waitgroups.hella撕开我的头发。

解释答案对我来说很棒。

3 个答案:

答案 0 :(得分:1)

在写入之前你正在读取频道,所以一切都会死锁,等待永远不会发生的读取。

您可以在调用c <- 0之前放置Printf来打破僵局,但程序可以打印0,1或2.请注意,如果您在开始之前输入初始发送第一个goroutine,你从另一个方向得到同样的问题,一个没有可能读取的发送。

如果你说你要做的事情会更容易提供帮助,因为我无法真正提供任何具体的指示。

答案 1 :(得分:0)

在最后一行之前添加:

c <- 0

这样你就可以给goroutines读取的起始值开始工作了。您也可以在最后一行(发送到频道)之前添加两个goroutines添加打印goroutine数字和值:

fmt.Println("goroutine 1 value", i)

您可以看到在渠道中同一项目的3个可能消费者的情况下如何传递值。很可能主要的goroutine将读取频道,你得到0。添加Sleep以给其他人一个机会。玩睡眠时间可以得到不同的结果。

答案 2 :(得分:0)

你有一个无缓冲的频道,这意味着你的工作&#34;同步&#34;我的意思是当使用无缓冲的通道时,你需要一个写入器和一个读取器来实现缓冲通道的尝试,因为你可以尝试选择等待消息。 2 - 您在从无缓冲通道写入之前正在读取,该通道将阻塞直到写入操作发生。所以你有两个来自被阻止频道的读者(因为那里没有作家)。