Closing a Channel of Unknown Length
In the provided code, the error "send on closed channel" occurs because multiple goroutines attempt to send values on a channel that has already been closed. This issue arises from the lack of synchronization between the goroutines, as one goroutine closes the channel while others are still sending data.
To effectively close a channel in this situation, it is essential to determine when all sender goroutines have completed their tasks. This can be achieved using a sync.WaitGroup to detect when all sender goroutines are done sending values.
Here's the modified code that uses a 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) }
In this solution, each sender goroutine adds one to the sync.WaitGroup to indicate that it will be sending values on the channel. The wg.Wait() in the close() goroutine ensures that the channel is closed only after all sender goroutines have completed their tasks, preventing the "send on closed channel" error.
The above is the detailed content of How to Safely Close a Channel of Unknown Length in Go?. For more information, please follow other related articles on the PHP Chinese website!