c:= make(chan int)和c:= make(chan int,1)之间有什么区别?

Hao*_*ang 3 channel go

我认为它们是相同的,但是在go内存模型中有这样的词:如果通道被缓冲(例如c = make(chan int, 1)),那么程序将不能保证打印"hello,world" - 它可能会打印出空字符串,崩溃或做其他事情.它是否正确?

ANi*_*sus 12

虽然埃文是对的,但我认为更长的解释可能有用:

Effective Go中所述,以下内容相同,并为您提供无缓冲的通道:

ci := make(chan int)            // unbuffered channel of integers
cj := make(chan int, 0)         // unbuffered channel of integers
Run Code Online (Sandbox Code Playgroud)

虽然有任何其他值会给你一个缓冲通道:

ck := make(chan int, 1)         // buffered channel of integers
Run Code Online (Sandbox Code Playgroud)

缓冲频道

使用缓冲通道,Go例程可以在通道(ck <- 42)中放置一个值,然后继续执行下一条指令,而不必等待某人从通道读取.除非通道缓冲区已满,否则这是真的.

如果一个通道已满,Go例程将等待另一个Go例程从通道读取,然后才能在其中放置自己的值.

无缓冲的频道

无缓冲的通道将无法存储任何数据.因此,为了使值通过无缓冲通道传递,发送Go例程将阻塞,直到接收Go例程收到该值.

因此,缓冲和无缓冲通道之间肯定存在差异.在内存模型案例中:

package main

var c = make(chan int)
var a string

func f() {
    a = "hello, world"
    <-c
}

func main() {
    go f()
    c <- 0
    print(a)
}
Run Code Online (Sandbox Code Playgroud)

如果你有一个缓冲信道var c = make(chan int, 1),则main()转到常规只想把一个值在缓冲区中,然后继续用print(a)中,也许前f()转到常规有时间设置a"hello, world".

但是在当前代码中,主Go例程将阻塞c <- 0,等待f()在继续打印之前接收该值,然后我们确定a已经设置为"hello, world".


Eva*_*van 4

make(chan int)生成一个无缓冲的通道,make(chan int, 1)生成一个缓冲区为 1 的通道。

有关差异的解释,请参阅http://golang.org/doc/ effective_go.html#channels。