【发布时间】:2018-07-29 15:39:29
【问题描述】:
我一直在尝试解决我在 Golang 并发中遇到的这个简单问题。我一直在寻找所有可能的解决方案,但没有发现任何特定于我的问题(或者我可能会错过一个)。这是我的代码:
package main
import (
"fmt"
"time"
)
func producer(ch chan int, d time.Duration, num int) {
for i:=0; i<num; i++ {
ch <- i
time.Sleep(d)
}
}
func main() {
ch := make(chan int)
go producer(ch, 100*time.Millisecond, 2)
go producer(ch, 200*time.Millisecond, 5)
for {
fmt.Println(<-ch)
}
close(ch)
}
打印错误:
致命错误:所有 goroutine 都处于休眠状态 - 死锁!
goroutine 1 [chan 接收]: main.main() D:/code/go/src/testconcurrency/main.go:23 +0xca 退出状态2
避免这个错误的有效方法是什么?,谢谢。
【问题讨论】:
-
你可以通过这个question
-
您的问题是您在通道中“发布”整数,然后您试图从主线程中读取它们。然后整数流停止,当 goroutine 结束时。 (当
producers 都结束时,不再向通道发布整数)并且您仍然在主线程上等待发布更多整数,这永远不会发生。在频道不再使用后,请尝试使用close(ch)关闭频道。 -
我做了
close(ch) -
你在导致死锁的地方关闭了它。您“在无限循环中”,一直在轮询通道,等待发布给它的任何整数。两个生产者都结束后,您仍在等待更多,而没有生产。
close(ch)必须在生产者的末尾(但在您的情况下,这将很困难,因为您有 2 个生产者)。 -
先尝试,删除一个生产者,然后运行代码,同样的crash会发生。然后尝试将
close(ch)移动到生产者例程的末尾,会成功。但在 2 个生产者的情况下,您可能需要另一个渠道或其他东西,您需要更好的设计。
标签: go concurrency channel goroutine