How to wait until buffered channel (semaphore) is empty?
Use "worker pool" to process you data. It is cheeper than run goroutine for each int, allocate memory for variables inside it and so on...
ints := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
ch := make(chan int)
var wg sync.WaitGroup
// run worker pool
for i := 2; i > 0; i-- {
wg.Add(1)
go func() {
defer wg.Done()
for id := range ch {
// do something
fmt.Println(id)
}
}()
}
// send ints to workers
for _, i := range ints {
ch <- i
}
close(ch)
wg.Wait()
You can't use a semaphore (channel in this case) in that manner. There's no guarantee it won't be empty any point while you are processing values and dispatching more goroutines. That's not a concern in this case specifically since you're dispatching work synchronously, but because there's no race-free way to check a channel's length, there's no primitive to wait for a channel's length to reach 0.
Use a sync.WaitGroup
to wait for all goroutines to complete
sem := make(chan struct{}, 2)
var wg sync.WaitGroup
for _, i := range ints {
wg.Add(1)
// acquire semaphore
sem <- struct{}{}
// start long running go routine
go func(id int) {
defer wg.Done()
// do something
// release semaphore
<-sem
}(i)
}
wg.Wait()