1. 使用channel来等待goroutine的结束
func createWorker(id int) worker {
w := worker{
in: make(chan int),
done: make(chan bool),
}
go doWorker(id, w.in, w.done)
return w
}

type worker struct {
in chan int
done chan bool
}

func doWorker(id int, c chan int, done chan bool) {
for n := range c {
//n, ok := <-c
//if !ok {
// break
//}
fmt.Printf("Worker %d received %c\n", id, n)

go func() { done <- true }()
}
}

func demoChan() {
var workers [10]worker
for i := 0; i < 10; i++ {
workers[i] = createWorker(i)
}

for i, worker := range workers {
worker.in <- 'a' + i
}

for i, worker := range workers {
worker.in <- 'A' + i
}

//wait for of done
for _, worker := range workers {
<-worker.done
<-worker.done

}
}
2. 使用 waitGroup
func createWait(id int, wg *sync.WaitGroup) wait {
w := wait{
in: make(chan int),
done: func() {
wg.Done()
},
}
go doWait(id, w)
return w
}

type wait struct {
in chan int
done func()
}

func doWait(id int, w wait) {
for n := range w.in {
fmt.Printf("Worker %d received %c\n", id, n)
w.done()
}
}

func demoChanWait() {
var wg sync.WaitGroup

var waits [10]wait
for i := 0; i < 10; i++ {
waits[i] = createWait(i, &wg)
}

wg.Add(20)
for i, worker := range waits {
worker.in <- 'a' + i
}

for i, worker := range waits {
worker.in <- 'A' + i
}
wg.Wait()
}