我想知道,如果去語言允許檢查多渠道正準備在同一時間。這是我正在嘗試做的一個有點人為的例子。(實際原因是看能否在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 關注
- 189 瀏覽
添加回答
舉報
0/150
提交
取消