With your example, you would most likely just use a WaitGroup like so:
package main
import (
"fmt"
"sync"
)
func worker(end, number int, chanel chan<- string, wg *sync.WaitGroup) {
for i := 0; i < end; i++ {
chanel <- fmt.Sprintf("%d in %d done", i, number)
}
wg.Done() // Decrement wg's counter by 1.
}
func main() {
receiver := make(chan string)
// Create a new WaitGroup.
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1) // Add 1 to the wg counter.
go worker(10, i, receiver, &wg)
}
go func() {
// Wait for the wg counter to be 0 and then
// close the receiver channel.
wg.Wait()
close(receiver)
}()
// range will finish once receiver is closed above.
for elem := range receiver {
fmt.Println(elem)
}
fmt.Println("Done!")
}