我想知道,如果去语言允许检查多渠道正准备在同一时间。这是我正在尝试做的一个有点人为的例子。(实际原因是看能否在go中原生实现petrinet)package mainimport "fmt"func mynet(a, b, c, d <-chan int, res chan<- int) { for { select { case v1, v2 := <-a, <-b: res <- v1+v2 case v1, v2 := <-c, <-d: res <- v1-v2 } }}func main() { a := make(chan int) b := make(chan int) c := make(chan int) d := make(chan int) res := make(chan int, 10) go mynet(a, b, c, d, res) a <- 5 c <- 5 d <- 7 b <- 7 fmt.Println(<-res) fmt.Println(<-res)}这不会如图所示编译。它可以通过只检查一个通道来编译,但是如果该通道准备好而另一个通道没有准备好,它可能会很容易死锁。package mainimport "fmt"func mynet(a, b, c, d <-chan int, res chan<- int) { for { select { case v1 := <-a: v2 := <-b res <- v1+v2 case v1 := <-c: v2 := <-d res <- v1-v2 } }}func main() { a := make(chan int) b := make(chan int) c := make(chan int) d := make(chan int) res := make(chan int, 10) go mynet(a, b, c, d, res) a <- 5 c <- 5 d <- 7 //a <- 5 b <- 7 fmt.Println(<-res) fmt.Println(<-res)}在一般情况下,我可能有多个案例在同一个频道上等待,例如case v1, v2 := <-a, <-b:...case v1, v2 := <-a, <-c:...所以当一个值在通道 a 上准备好时,我不能提交到任何一个分支:只有当所有值都准备好时。
2 回答
慕雪6442864
TA贡献1812条经验 获得超5个赞
您不能同时在多个频道上进行选择。您可以做的是实现一个扇入模式,以合并来自多个渠道的值。
基于您的代码的粗略示例可能如下所示:
func collect(ret chan []int, chans ...<-chan int) {
ints := make([]int, len(chans))
for i, c := range chans {
ints[i] = <-c
}
ret <- ints
}
func mynet(a, b, c, d <-chan int, res chan<- int) {
set1 := make(chan []int)
set2 := make(chan []int)
go collect(set1, a, b)
go collect(set2, c, d)
for {
select {
case vs := <-set1:
res <- vs[0] + vs[1]
case vs := <-set2:
res <- vs[0] + vs[1]
}
}
}
- 2 回答
- 0 关注
- 164 浏览
添加回答
举报
0/150
提交
取消