为了账号安全,请及时绑定邮箱和手机立即绑定

Goroutines 通道和“停止”

Goroutines 通道和“停止”

Go
Smart猫小萌 2021-12-06 17:13:18
我正在阅读/工作Go Concurrency Patterns: Pipelines and cancel,但我无法理解停止短部分。我们有以下功能:func sq(in <-chan int) <-chan int {    out := make(chan int)    go func() {        for n := range in {            out <- n * n        }        close(out)    }()    return out}func gen(nums ...int) <-chan int {    out := make(chan int)    go func() {        for _, n := range nums {            out <- n        }        close(out)    }()    return out}func merge(cs ...<-chan int) <-chan int {    var wg sync.WaitGroup    out := make(chan int, 1) // enough space for the unread inputs    // Start an output goroutine for each input channel in cs.  output    // copies values from c to out until c is closed, then calls wg.Done.    output := func(c <-chan int) {        for n := range c {            out <- n        }        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}func main() {    in := gen(2, 3)    // Distribute the sq work across two goroutines that both read from in.    c1 := sq(in)    c2 := sq(in)    // Consume the first value from output.    out := merge(c1, c2)    fmt.Println(<-out) // 4 or 9    return    // Apparently if we had not set the merge out buffer size to 1    // then we would have a hanging go routine. }现在,如果您注意到 line 2in merge,它表示我们chan使用buffer大小为 1的 out ,因为这是未读输入的足够空间。不过,我几乎可以肯定,我们应该分配chan与buffer大小2.根据此代码示例:c := make(chan int, 2) // buffer size 2c <- 1  // succeeds immediatelyc <- 2  // succeeds immediatelyc <- 3  // blocks until another goroutine does <-c and receives 1 由于本节意味着一个chan的buffer大小3将不会阻止。任何人都可以澄清/帮助我理解吗?
查看完整描述

1 回答

?
慕工程0101907

TA贡献1887条经验 获得超5个赞

程序向通道发送两个值并从通道out读取一个值out。未接收到其中一个值。

如果通道没有缓冲(容量 0),那么其中一个发送 goroutine 将阻塞,直到程序退出。这是泄漏。

如果创建的通道容量为 1,则两个 goroutine 都可以发送到通道并退出。发送到通道的第一个值由 接收main。第二个值保留在通道中。

如果 main 函数没有从 channel 接收到一个值out,那么需要一个容量为 2 的 channel 来防止 goroutines 无限期地阻塞。



查看完整回答
反对 回复 2021-12-06
  • 1 回答
  • 0 关注
  • 166 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信