關閉未知長度的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中文網其他相關文章!