无缓冲通道 - 多值传递

package main


import (

    "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通道没有缓冲,它不应该造成死锁吗?我错过了什么?


至尊宝的传说
浏览 89回答 2
2回答

萧十郎

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

猛跑小猪

按照它的工作原理:in := make(chan int, 10) out := make(chan int)上面你正在创建两个通道。in被缓冲可以容纳 10 个值。out无缓冲只能保存 1 个值对于我:= 0;我 < 10;&nbsp;i++ { 在 <- i }在上面,您正在向您的输入频道添加 10 个值 [0-9]逼近)上面你正在关闭in频道上的写入。请记住,继续阅读in仍然是开放的。去函数(){您正在创建一个 go 例程来读取in通道的值。(最佳实践实际上是将 func 传递in给 func ,但这不是这里的重点。&nbsp;&nbsp;&nbsp;for&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i,&nbsp;ok&nbsp;:=&nbsp;<-in在您的循环上方,您读取值直到in为空(为空ok时为假)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;!ok&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(out) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}当您out完成从in.&nbsp;直到下面的行执行。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out&nbsp;<-&nbsp;i&nbsp;*&nbsp;2&nbsp;//THIS&nbsp;LINE在上面你写入通道out并阻塞这个 goroutine 直到它的值被读取。循环将持续 10 次。for v := range out { // AND HERE fmt.Println(v) }上面,回到主 goroutine,您将从 读取值out,阻塞并将控制权传递给另一个 goroutine。这一直持续到 for 循环中断并out关闭。
打开App,查看更多内容
随时随地看视频慕课网APP