简体   繁体   English

使用缓冲通道运行 goroutine,在将元素输入通道之前我得到了一个输出

[英]Run goroutine with buffered channel, I got an output before input an element into an channel

package main

import (
    "fmt"
    "time"
)

func send(ch chan int, size int) {
    for i := size; i < size+10; i++ {
        ch <- i
        fmt.Printf("put val %v in channel\n", i)
    }
    // close(ch)
}

func main() {
    ch1 := make(chan int, 2)
    ch2 := make(chan int, 1)
    // defer close(ch1)
    // defer close(ch2)

    go send(ch1, 0)
    go send(ch2, 20)

    time.Sleep(time.Second)

    for {
        select {
        case val := <-ch1:
            fmt.Printf("read val %v from chl\n", val)
        case val := <-ch2:
            fmt.Printf("read val %v from ch2\n", val)
        case <-time.After(2 * time.Second): //这里是从阻塞的channel中超时返回的小技巧
            fmt.Println("Time out")
            return
        }
    }

}

I run this code, and I got read val 2 from chl before put val 2 in channel .我运行此代码,并在put val 2 in channel之前read val 2 from chl I don't know how it comes from.我不知道它是怎么来的。 It's seem reasonable to read after put new value in channel1.将新值放入 channel1 后读取似乎是合理的。

An example of output is:输出的一个例子是:

put val 20 in channel
put val 0 in channel
put val 1 in channel
put val 2 in channel
read val 0 from chl
read val 1 from chl
read val 20 from ch2
read val 21 from ch2
put val 3 in channel
put val 21 in channel
put val 22 in channel
read val 2 from chl
read val 3 from chl
read val 4 from chl
read val 22 from ch2
read val 23 from ch2
put val 4 in channel
put val 5 in channel
put val 6 in channel
put val 7 in channel
read val 5 from chl
read val 6 from chl
read val 7 from chl
read val 8 from chl
put val 8 in channel
put val 9 in channel
read val 9 from chl
put val 23 in channel
put val 24 in channel
put val 25 in channel
read val 24 from ch2
read val 25 from ch2
put val 26 in channel
put val 27 in channel
read val 26 from ch2
read val 27 from ch2
read val 28 from ch2
put val 28 in channel
put val 29 in channel
read val 29 from ch2
Time out

in your send() function, the line fmt.Printf("put val %v in channel\\n", i) is executed after a value has been send to the buffered channel Since you are running this in a goroutine, it is possible that the loop receives value before the goroutine can print the value, because goroutines run concurrently.在你的send()函数中, fmt.Printf("put val %v in channel\\n", i)在一个值被发送到缓冲通道后执行 因为你在 goroutine 中运行它,所以有可能循环在 goroutine 可以打印值之前接收值,因为 goroutines 并发运行。 Concurrently means it may be parallel, maybe not.同时意味着它可能是并行的,也可能不是。 This makes it unpredictable in terms of order of execution (for the spawned goroutines), but guarantees completion这使得它在执行顺序方面不可预测(对于产生的 goroutines),但保证完成
Side note: Sending a value to a buffered channel blocks in case the channel is full, hence your code has more than one possible source for the behavior displayed, in case this occurs when the buffer is full (maybe for other numbers in the loop), although not guaranteed to happen旁注:如果通道已满,则将值发送到缓冲通道会阻止,因此您的代码具有多个可能的显示行为来源,以防在缓冲区已满时发生这种情况(可能用于循环中的其他数字) ,虽然不能保证发生

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

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