【发布时间】:2018-09-20 20:10:16
【问题描述】:
我正在尝试使用一个 for 循环,该循环不断地将字符串发送到由不同 goroutine 读取的不同通道。但是,它给了我错误“所有 goroutines 都在睡觉 - 死锁!”为什么会这样?我搜索了一些答案,但找不到适合这种情况的答案。
func main() {
var chans []chan string
for i := 0; i < 3; i++ {
chans = append(chans, make(chan string))
}
for i := 0; i < 3; i++ {
go sendString(chans[i])
}
for str := range chans[0] {
fmt.Print(str)
}
}
func sendString(ch chan string) {
ch <- "a"
ch <- "b"
ch <- "c"
ch <- "d"
}
错误在这里。它打印“abcd”,然后产生错误,如果我删除循环打印,程序不会产生错误。
abcdfatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
C:/Users/YuanZheng Hu/Desktop/Go Test/test/test.go:18 +0x28d
goroutine 19 [chan send]:
main.sendString(0xc04203c120)
C:/Users/YuanZheng Hu/Desktop/Go Test/test/test.go:24 +0x42
created by main.main
C:/Users/YuanZheng Hu/Desktop/Go Test/test/test.go:15 +0x175
goroutine 20 [chan send]:
main.sendString(0xc04203c180)
C:/Users/YuanZheng Hu/Desktop/Go Test/test/test.go:24 +0x42
created by main.main
C:/Users/YuanZheng Hu/Desktop/Go Test/test/test.go:15 +0x175
exit status 2
我使用 WaitGroup 做了版本,但它似乎不正确,并且给了我同样的错误“所有 goroutines 都睡着了 - 死锁!”我在下面的代码中哪里做错了?
func main() {
var myWaitGroup sync.WaitGroup
ch := make(chan string)
myWaitGroup.Add(1)
go sendString(ch, &myWaitGroup)
myWaitGroup.Wait()
close(ch)
time.Sleep(1 * time.Second)
}
func sendString(ch chan string, pg *sync.WaitGroup) {
ch <- "a"
ch <- "b"
ch <- "c"
ch <- "d"
defer pg.Done()
}
【问题讨论】:
-
@TrippKinetics 我猜对于那个问题,他关闭了通道,并使用另一个输出结果,但我想说的是,有没有办法只使用打印通道中的元素一个通道,不使用另一个 goroutine 中的接收函数
-
如果你想把所有的字符串放到一个单独的通道中,你可以使用一个 sync.WaitGroup 来等待所有的 goroutine 完成然后在 main goroutine 中关闭这个通道