channel关闭---多写一读
2018-12-19 本文已影响0人
bocsoft
这种场景下虽然可以用 sync.Once 来解决多个写入端重复关闭 channel 的问题,但更优雅的办法设置一个额外的 channel ,由读取端通过关闭来通知写入端任务完成不要再继续再写入数据了:
package main
import (
"fmt"
"sync"
)
//多写一读:这种场景下虽然可以用 sync.Once 来解决多个写入端重复关闭 channel 的问题,但更优雅的办法设置一个额外的 channel ,
// 由读取端通过关闭来通知写入端任务完成不要再继续再写入数据了
func main() {
wg := &sync.WaitGroup{}
ch := make(chan int, 100)
done := make(chan struct{})
send := func(id int) {
defer wg.Done()
for i := 0; ; i++ {
select {
case <-done: //接到通知,已完成任务,不再写入
//get exit signal
fmt.Printf("sender #%d exit\n", id)
return
case ch <- id*10 + i:
}
}
}
recv := func() {
count := 0
for i := range ch {
fmt.Printf("receiver get %d\n", i)
count++
if count >= 10 {
//signal receiving finish
close(done) //关闭,通知不需要再写入了
return
}
}
}
wg.Add(3)
//多写
go send(0)
go send(1)
go send(2)
//一读
recv()
wg.Wait()
}
/*
输出结果为:
receiver get 20
receiver get 21
receiver get 22
receiver get 23
receiver get 24
receiver get 10
receiver get 11
receiver get 12
receiver get 13
receiver get 14
sender #0 exit
sender #2 exit
sender #1 exit
*/