如果发送到多个值,则通道未接收任何值



如果我传递超过 12 个totalValuesgetResults(),则不会从通道resultCh读取任何值,我得到fatal error: all goroutines are asleep - deadlock!

package main
type result struct {
index int
count int
}
func getResults(indexCh chan int, resultCh chan result, totalValues int) {
allFields := make([]int, totalValues)
for i := range allFields {
indexCh <- i
println("Sent value", i)
}
println("Sent all values")
for i := 0; i < totalValues; i++ {
value := <-resultCh
println("Received result", value.index)
allFields[value.index] = value.count
}
println("Done processing")
}
func processValue(indexCh chan int, ch chan result) {
for index := range indexCh {
println("Received value", index)
ch <- result{
index: index,
count: index * index,
}
println("Sent result", index)
}
}
func main() {
bufferDepth := 4
indexCh := make(chan int, bufferDepth)
resultCh := make(chan result, bufferDepth)
for i := 0; i < 4; i++ {
go processValue(indexCh, resultCh)
}
// Value > 12 results in goroutine asleep
getResults(indexCh, resultCh, 12)
}

上面的代码通过使用从缓冲通道indexCh读取值的函数processValue()启动四个goroutine来工作。整数 0 到totalValuesgetResults()插入到indexCh中。processValue()处理该值并将结果放入缓冲通道resultCh,由getResults()读取。

我只在totalValues大于 12 时才观察到这个问题。不会从resultCh读取任何值,因为"收到的结果..."未打印。

如果我将bufferDepth增加到 5,则程序成功完成 12totalValues>和 15 <。

如果resultCh的缓冲区深度与totalValues匹配,则程序也会成功完成。

getResults首先将所有值写入通道。有 4 个 goroutines 在侦听,因此每个 goroutines 都会拾取这些值,并且它们被阻止写入结果通道。通道的缓冲区大小为 4。因此,4 个 goroutines 每个程序可以在阻塞之前将总共 4 个值写入结果通道。

4 个 goroutines + 4 个索引通道大小 + 4 个结果通道大小 = 12 个条目

之后,processValue在写入通道时被阻止,因为getResults也被阻止写入indexCh

最新更新