2 回答

TA贡献1900条经验 获得超5个赞
我认为您遇到了僵局,因为您func2只消耗了1 个值ch,然后完成。然后其他func1goroutine 被卡住等待ch可以写入,他们不能这样做,因为ch在另一端没有其他 goroutine 可以读取。
由于您希望func2从chuntil开始持续消耗值ch,因此您需要func2像这样创建一个循环:
func func2(ch chan int) {
fmt.Println("func2")
for v := range ch {
fmt.Println(v)
}
}
这将保持func2“活跃”并阅读,ch直到你在close(ch)其他地方做。在您的示例中关闭的适当位置ch可能在mainafter wg.Wait()。
如果您想确保Println在程序完成之前看到所有语句的结果,您还应该使用一些同步机制来等待func2完成。否则main将立即结束,之后close(ch)可能会或可能不会在func2打印收到的每个值之前。
一种常见的技术是“完成”通道。例如:
func func2(ch chan int, done chan bool) {
fmt.Println("func2")
for v := range ch {
fmt.Println(v)
}
done <- true
}
并在main:
done := make(chan bool)
go func2(ch, done)
...
wg.Wait()
close(ch)
<-done
使用chan struct{}(empty struct) 也很常见,因为空结构不需要内存。

TA贡献1810条经验 获得超4个赞
您正在寻找的是一种在所有值都完成流式传输时关闭通道的干净方法。当新值出现时,您可以创建一个新通道并开始在此流式传输值。我就是这样做的,也许有帮助
var wg sync.WaitGroup
toUpdate := make(chan *someType, BufferSize)
for i := 0; i < BufferSize; i++ {
go processEvents(toUpdate, &wg)
}
// // wait till all the checks have come back
go func(toUpdate chan * someType, group *sync.WaitGroup) {
group.Wait()
close(toCreate)
}(toCreate, toUpdate, &wg)
- 2 回答
- 0 关注
- 99 浏览
添加回答
举报