Playing with go, I compiled this code:
package main import "fmt" const N = 10 func main() { ch := make(chan int, N) done := make(chan bool) for i := 0; i < N; i++ { go (func(n int, ch chan int, done chan bool) { for i := 0; i < N; i++ { ch <- n*N + i } done <- true })(i, ch, done) } numDone := 0 for numDone < N { select { case i := <-ch: fmt.Println(i) case <-done: numDone++ } } for { select { case i := <-ch: fmt.Println(i) default: return } } }
Basically, I have N channels that do some work and report it on one channel - I want to know when all the channels will be completed. Therefore, I have this other done channel, which every working goroutine sends a message (the message does not matter), and this forces main to consider this thread as executed. When the counter reaches N, we are actually done.
Is it "good"? Is there a more idiomatic way to do this?
edit: To clarify a bit, I doubt because the done channel seems to be doing the job for which it seems like closing the channel, but of course I can't actually close the channel in any goroutine, because all the routines use the same channel. Therefore, I use done to simulate a channel that does some kind of "buffered close".
edit2: The source code did not work, because sometimes the done signal from the procedure was read before int just put on ch . A โclean upโ cycle is required.
source share