关闭未知长度的 Channel
在提供的代码中,出现错误“在关闭的通道上发送”,因为多个 goroutine 尝试发送已关闭通道上的值。这个问题是由于 Goroutine 之间缺乏同步造成的,因为一个 Goroutine 关闭了通道,而其他 Goroutine 仍在发送数据。
为了在这种情况下有效地关闭通道,必须确定所有发送者 Goroutine 何时关闭通道完成了他们的任务。这可以通过使用sync.WaitGroup来检测所有发送者协程何时完成发送值来实现。
这是使用sync.WaitGroup的修改后的代码:
func gen(ch chan int, wg *sync.WaitGroup) { defer wg.Done() var i int for { time.Sleep(time.Millisecond * 10) ch <- i i++ // when no more data (e.g. from db, or event stream) if i > 100 { break } } } func receiver(ch chan int) { for i := range ch { fmt.Println("received:", i) } } func main() { ch := make(chan int) wg := &sync.WaitGroup{} for i := 0; i < 10; i++ { wg.Add(1) go gen(ch, wg) } go func() { wg.Wait() close(ch) }() receiver(ch) }
在此解决方案中,每个发送者 goroutine 都会向sync.WaitGroup 添加 1,以指示它将在通道上发送值。 close() goroutine 中的 wg.Wait() 确保只有在所有发送者 goroutine 完成其任务后才关闭通道,从而防止“在关闭的通道上发送”错误。
以上是如何安全地关闭 Go 中未知长度的通道?的详细内容。更多信息请关注PHP中文网其他相关文章!