Я хотел бы знать, может ли язык go проверять наличие нескольких каналов, готовых к отправке в то же время.Проверка одновременных каналов, готовых к работе
Вот несколько надуманный пример того, что я пытаюсь сделать. (Реальная причина, чтобы увидеть, если я могу реализовать в родной Петри ходу)
package main
import "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 main
import "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: только когда все значения готовы.
Nope. Вы можете сделать неблокирующий прием (используя «select» с одним случаем получения и «по умолчанию») на канале, чтобы не блокировать, если 'b' не готов (но тогда вы уже взяли значение из' a '), и вы можете сделать' len() 'на буферизованном канале, чтобы спекулятивно проверить, сколько элементов находится в буфере (хотя это может измениться до того, как ваш прием будет выполнен). – twotwotwo