package main import ( "fmt" "os" "strconv" "sync" ) func go1(ch chan<- string, wg1 *sync.WaitGroup) { defer wg1.Done() for i := 1; i < 11; i++ { ch <- "go1_" + strconv.Itoa(i) } } func go2(ch chan<- string, wg1 *sync.WaitGroup) { defer wg1.Done() for i := 1; i < 11; i++ { ch <- "go2_" + strconv.Itoa(i) } } func Reader(ch <-chan string, wg *sync.WaitGroup) { defer wg.Done() for { if v, ok := <-ch; !ok { fmt.Println("Channel closed") os.Exit(1) } else { fmt.Println(v) } } } func main() { var wg1 sync.WaitGroup var wg sync.WaitGroup wg.Add(1) wg1.Add(2) ch := make(chan string) go go1(ch, &wg1) go go2(ch, &wg1) go Reader(ch, &wg) go func() { wg1.Wait() close(ch) }() wg.Wait() }