Or-Channel
使用场景:
当你需要同时监测多个信号时,只要接收到其中任一个信号,就认为信号接收成功,需要进行下一步处理代码:
func or(channels ...<-chan interface{}) <-chan interface{} { switch len(channels) { case 0: return nil case 1: return channels[0] } orDone := make(chan interface{}) go func() { defer close(orDone) switch len(channels) { case 2: select { case <-channels[0]: case <-channels[1]: } default: select { case <-channels[0]: case <-channels[1]: case <-channels[2]: case <-or(append(channels[3:], orDone)...): } } }() return orDone }
测试:
func TestOr(t *testing.T) { st := time.Now() r := rand.New(rand.NewSource(time.Now().Unix())) <-or( randSig(r), randSig(r), randSig(r), randSig(r), randSig(r), ) fmt.Printf("closed after %v!\n", time.Since(st)) } func randSig(r *rand.Rand) <-chan interface{} { ch := make(chan interface{}) go func() { defer close(ch) sec := time.Duration(r.Int63n(10)+3) * time.Second fmt.Printf("closing after %v!\n", sec) time.Sleep(sec) }() return ch }
结果:
closing after 4s! closing after 10s! closing after 3s! closing after 9s! closing after 11s! closed after 3.001062582s!