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

无缓冲通道 - 多值传递

无缓冲通道 - 多值传递

Go
至尊宝的传说 2022-06-13 15:55:41
package mainimport (    "fmt")func main() {    in := make(chan int, 10)    out := make(chan int)    for i := 0; i < 10; i++ {        in <- i    }    close(in)    go func() {        for {            i, ok := <-in            if !ok {                close(out)                break            }            out <- i * 2 //THIS LINE        }    }()    for v := range out { // AND HERE        fmt.Println(v)    }}我对 Go 有点陌生,了解了缓冲通道和无缓冲通道之间的区别,但我不确定这段代码是如何工作的。由于out通道没有缓冲,它不应该造成死锁吗?我错过了什么?
查看完整描述

2 回答

?
萧十郎

TA贡献1815条经验 获得超12个赞

outchannel 是无缓冲的,所以如果你在没有另一个 goroutine 等待读取它的情况下写入它,它将阻塞。读取也一样:它将阻塞,直到另一个 goroutine 写入它。因此,goroutine 在写入时阻塞,直到 main 中的 for 循环从中读取。主 goroutine 会从 out 读取直到它关闭,所以当 goroutine 最终关闭时,for 循环终止。



查看完整回答
反对 回复 2022-06-13
?
猛跑小猪

TA贡献1858条经验 获得超8个赞

按照它的工作原理:

in := make(chan int, 10) out := make(chan int)

上面你正在创建两个通道。in被缓冲可以容纳 10 个值。out无缓冲只能保存 1 个值

对于我:= 0;我 < 10; i++ { 在 <- i }

在上面,您正在向您的输入频道添加 10 个值 [0-9]

逼近)

上面你正在关闭in频道上的写入。请记住,继续阅读in仍然是开放的。

去函数(){

您正在创建一个 go 例程来读取in通道的值。(最佳实践实际上是将 func 传递in给 func ,但这不是这里的重点。

   for {
       i, ok := <-in

在您的循环上方,您读取值直到in为空(为空ok时为假)

       if !ok {
                  close(out)
                             break
       }

当您out完成从in. 直到下面的行执行。

       out <- i * 2 //THIS LINE

在上面你写入通道out并阻塞这个 goroutine 直到它的值被读取。循环将持续 10 次。

for v := range out { // AND HERE fmt.Println(v) }

上面,回到主 goroutine,您将从 读取值out,阻塞并将控制权传递给另一个 goroutine。这一直持续到 for 循环中断并out关闭。


查看完整回答
反对 回复 2022-06-13
  • 2 回答
  • 0 关注
  • 87 浏览
慕课专栏
更多

添加回答

举报

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