我试图更多地了解 go 的通道和 goroutines,所以我决定制作一个小程序来计算文件中的单词,由bufio.NewScanner
对象读取:
nCPUs := flag.Int("cpu", 2, "number of CPUs to use")
flag.Parse()
runtime.GOMAXPROCS(*nCPUs)
scanner := bufio.NewScanner(file)
lines := make(chan string)
results := make(chan int)
for i := 0; i < *nCPUs; i++ {
go func() {
for line := range lines {
fmt.Printf("%s\n", line)
results <- len(strings.Split(line, " "))
}
}()
}
for scanner.Scan(){
lines <- scanner.Text()
}
close(lines)
acc := 0
for i := range results {
acc += i
}
fmt.Printf("%d\n", acc)
现在,在我迄今为止发现的大多数示例中,通道lines
和results
通道都会被缓冲,例如make(chan int, NUMBER_OF_LINES_IN_FILE)
. 尽管如此,在运行此代码后,我的程序仍然存在并显示fatal error: all goroutines are asleep - deadlock!
错误消息。
基本上我的想法是我需要两个通道:一个与 goroutine 通信文件中的行(因为它可以是任何大小,我不喜欢认为我需要在make(chan)
函数调用中通知大小。其他通道会从 goroutine 收集结果,在主函数中我会用它来计算一个累积的结果。
使用 goroutine 和通道以这种方式编程的最佳选择应该是什么?任何帮助深表感谢。