猿问

检查同步通道是否准备就绪

我想知道,如果去语言允许检查多渠道正准备在同一时间。


这是我正在尝试做的一个有点人为的例子。(实际原因是看能否在go中原生实现petrinet)


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 上准备好时,我不能提交到任何一个分支:只有当所有值都准备好时。


繁星点点滴滴
浏览 165回答 2
2回答

慕雪6442864

您不能同时在多个频道上进行选择。您可以做的是实现一个扇入模式,以合并来自多个渠道的值。基于您的代码的粗略示例可能如下所示:func collect(ret chan []int, chans ...<-chan int) {&nbsp; &nbsp; ints := make([]int, len(chans))&nbsp; &nbsp; for i, c := range chans {&nbsp; &nbsp; &nbsp; &nbsp; ints[i] = <-c&nbsp; &nbsp; }&nbsp; &nbsp; ret <- ints}func mynet(a, b, c, d <-chan int, res chan<- int) {&nbsp; &nbsp; set1 := make(chan []int)&nbsp; &nbsp; set2 := make(chan []int)&nbsp; &nbsp; go collect(set1, a, b)&nbsp; &nbsp; go collect(set2, c, d)&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case vs := <-set1:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res <- vs[0] + vs[1]&nbsp; &nbsp; &nbsp; &nbsp; case vs := <-set2:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res <- vs[0] + vs[1]&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Go
我要回答