[英]Is it possible to safely close a channel once from multiple goroutines using select?
[英]Go Select and multiple cases at once
当同时接收到C1和C2时,如何使以下代码适应某些情况https://gobyexample.com/select
import "time"
import "fmt"
func main() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
time.Sleep(time.Second * 1)
c1 <- "one"
}()
go func() {
time.Sleep(time.Second * 2)
c2 <- "two"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
}
}
}
那可能是一种管道技术,称为扇入 :
一个功能可以从多个输入中读取并继续进行操作,直到将所有通道都多路复用到一个关闭所有输入都已关闭的通道上,然后关闭所有通道。 这称为扇入。
func merge(cs ...<-chan int) <-chan int {
var wg sync.WaitGroup
out := make(chan string)
// Start an output goroutine for each input channel in cs. output
// copies values from c to out until c is closed or it receives a value
// from done, then output calls wg.Done.
output := func(c <-chan string) {
for n := range c {
select {
case out <- "received " + n:
case <-done:
}
}
wg.Done()
}
wg.Add(len(cs))
for _, c := range cs {
go output(c)
}
// Start a goroutine to close out once all the output goroutines are
// done. This must start after the wg.Add call.
go func() {
wg.Wait()
close(out)
}()
return out
}
注意:无论您最终使用什么解决方案,都请阅读:
Alan Shreve 设计带有通道的Go API的原理 。
尤其是:
API应该声明其通道的方向性 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.