我在 Go Playground 中运行此代码:https://play.golang.org/p/1gqgXZXDhsF但它以僵局结束:
package main
import (
"fmt"
"time"
)
func createFakeReadData(r map[int]chan string, n int) {
for {
time.Sleep(time.Duration(n - 1) * time.Second)
r[n] <- string(n)
}
}
func log(l <-chan string) {
fmt.Println(<-l)
}
func main() {
logChan := make(chan string)
go log(logChan)
rChanMap := make(map[int]chan string)
rChanMap[5] = make(chan string)
rChanMap[6] = make(chan string)
rChanMap[7] = make(chan string)
rChanMap[8] = make(chan string)
go createFakeReadData(rChanMap, 5)
go createFakeReadData(rChanMap, 6)
go createFakeReadData(rChanMap, 7)
go createFakeReadData(rChanMap, 8)
for {
var f string
select {
case f = <-rChanMap[5]:
logChan <- f
case f = <-rChanMap[6]:
logChan <- f
case f = <-rChanMap[7]:
logChan <- f
case f = <-rChanMap[8]:
logChan <- f
}
}
}
fatal error: all goroutines are asleep - deadlock!
我在 main 中有 5 个 goroutine 和一个 select 语句,控制其中的 4 个(读者)。第 5 个(记录器)只是坐下来等待任何内容通过 channel 发送给它。当 4 个读取器中的一个从 channel 获取输入时,它应该在 select 语句中触发“案例”,然后尝试将该数据向前发送到记录器 channel 。
我很新去 channel 。我了解什么是死锁以及可能发生的某些情况,尤其是在使用无缓冲 channel 时。但这在我看来应该可行。
在此先感谢您的帮助。
最佳答案
createFakeReadData
将字符串无休止地发送到 rChanMap[5]
等 channel 中.
但是在 log
您只能从输出 channel 接收一次:
func log(l <-chan string) {
fmt.Println(<-l)
}
由于您创建的所有 channel 都是无缓冲的,如果没有从输出 channel 接收 goroutine
logChan
,其他 goroutine 将永远阻止尝试发送给它。您可能想要更改
log
功能如下:func log(l <-chan string) {
for m := range l {
fmt.Println(m)
}
}
这样,它将从 channel 接收,直到它关闭。
顺便说一句,一些免费的建议:
string(n)
不会将整数转换为字符串,请尝试搜索正确的方法来执行此操作关于go - 为什么会陷入僵局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59331267/