简体   繁体   English

无缓冲通道 - 多值传递

[英]unbuffered channel - multiple value passing

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)
    }
}

I am a bit new to Go and learned the difference between buffered and unbuffered channels, but I am not sure how this code works.我对 Go 有点陌生,并了解了缓冲和非缓冲通道之间的区别,但我不确定这段代码是如何工作的。 Since the out channel is not buffered should not it create deadlock?由于out通道没有缓冲,它不应该造成死锁吗? What am I missing?我错过了什么?

out channel is unbuffered so if you write to it without another goroutine waiting to read from it, it will block. out通道是无缓冲的,所以如果你在没有另一个 goroutine 等待读取的情况下写入它,它将阻塞。 Same for read: it will block until another goroutine writes to it.读取也一样:它将阻塞,直到另一个 goroutine 写入它。 So, the goroutine blocks on write to out until the for loop in main reads from it.因此,goroutine 在写入时阻塞,直到 main 中的 for 循环从中读取。 The main goroutine will read from out until it is closed, so when the goroutine finally closes out, the for loop terminates.主 goroutine 会从 out 读取直到它关闭,所以当 goroutine 最终关闭时,for 循环终止。

Following how it is working:按照它的工作原理:

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

Above you are creating two channels.上面你正在创建两个通道。 in is buffered can hold 10 values. in is buffered 可以容纳 10 个值。 out is unbuffered can hold only 1 value out是无缓冲的,只能保存 1 个值

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

Above you are adding 10 values [0-9] to your in channel在上面,您正在向您的输入频道添加 10 个值 [0-9]

close(in)逼近)

Above you are closing write on in channel.上面你正在关闭频道in的写入。 Keep in mind read on in is still open.请记住in继续阅读仍然是开放的。

go func() { go func() {

You are creating a go routine to read values of in channel.您正在创建一个 go 例程来读取通道内in值。 (Best practice really is to pass the in to the func but that's not of focus here. (最佳实践实际上是将in传递给 func ,但这不是这里的重点。

 for { i, ok:= <-in

Above in your loop you read value till in is empty ( ok will be false when it's empty)在您的循环上方,您读取 value 直到in为空(当它为空时ok将为 false )

 if !ok { close(out) break }

Above you would close out and break when you are done reading values from in .当您完成从in读取值时,您将out上面关闭并中断。 Till then below line executes.直到下面的行执行。

 out <- i * 2 //THIS LINE

Above you write to channel out and block this goroutine till it's value is read.在上面你写入通道out阻塞这个 goroutine 直到它的值被读取。 The cycle would continue 10 times.循环将持续 10 次。

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

Above, back in main goroutine, you would read value from out , block and pass control to the other goroutine.上面,回到主 goroutine,您将从out读取值,阻塞并将控制权传递给另一个 goroutine。 This continues till for loop breaks and out is closed.这一直持续到 for 循环中断并且out关闭。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM