我正在阅读/工作Go Concurrency Patterns: Pipelines and cancel,但我无法理解停止短部分。我们有以下功能:func sq(in <-chan int) <-chan int { out := make(chan int) go func() { for n := range in { out <- n * n } close(out) }() return out}func gen(nums ...int) <-chan int { out := make(chan int) go func() { for _, n := range nums { out <- n } close(out) }() return out}func merge(cs ...<-chan int) <-chan int { var wg sync.WaitGroup out := make(chan int, 1) // enough space for the unread inputs // Start an output goroutine for each input channel in cs. output // copies values from c to out until c is closed, then calls wg.Done. output := func(c <-chan int) { for n := range c { out <- n } wg.Done() } wg.Add(len(cs)) for _, c := range cs { go output(c) } // Start a goroutine to close out once all the output goroutines are // done. This must start after the wg.Add call. go func() { wg.Wait() close(out) }() return out}func main() { in := gen(2, 3) // Distribute the sq work across two goroutines that both read from in. c1 := sq(in) c2 := sq(in) // Consume the first value from output. out := merge(c1, c2) fmt.Println(<-out) // 4 or 9 return // Apparently if we had not set the merge out buffer size to 1 // then we would have a hanging go routine. }现在,如果您注意到 line 2in merge,它表示我们chan使用buffer大小为 1的 out ,因为这是未读输入的足够空间。不过,我几乎可以肯定,我们应该分配chan与buffer大小2.根据此代码示例:c := make(chan int, 2) // buffer size 2c <- 1 // succeeds immediatelyc <- 2 // succeeds immediatelyc <- 3 // blocks until another goroutine does <-c and receives 1 由于本节意味着一个chan的buffer大小3将不会阻止。任何人都可以澄清/帮助我理解吗?
1 回答
慕工程0101907
TA贡献1887条经验 获得超5个赞
程序向通道发送两个值并从通道out
读取一个值out
。未接收到其中一个值。
如果通道没有缓冲(容量 0),那么其中一个发送 goroutine 将阻塞,直到程序退出。这是泄漏。
如果创建的通道容量为 1,则两个 goroutine 都可以发送到通道并退出。发送到通道的第一个值由 接收main
。第二个值保留在通道中。
如果 main 函数没有从 channel 接收到一个值out
,那么需要一个容量为 2 的 channel 来防止 goroutines 无限期地阻塞。
- 1 回答
- 0 关注
- 166 浏览
添加回答
举报
0/150
提交
取消