Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between c:=make(chan int) and c:=make(chan int,1)?

Tags:

go

channel

I think they're the same, but there is a such words in The go memory model:, if the channel were buffered (e.g., c = make(chan int, 1)) then the program would not be guaranteed to print "hello, world" – it might print the empty string, crash, or do something else. Is this correct?

like image 500
Hao Wang Avatar asked Apr 23 '14 01:04

Hao Wang


2 Answers

While Evan is right, I thought a longer explanation might be useful:

As stated in Effective Go, the following are the same and gives you unbuffered channels:

ci := make(chan int)            // unbuffered channel of integers
cj := make(chan int, 0)         // unbuffered channel of integers

While having any other value would give you a buffered channel:

ck := make(chan int, 1)         // buffered channel of integers

Buffered channel

With a buffered channel, a Go routine may put a value in the channel ( ck <- 42 ) and then continue on with the next instruction without having to wait for someone to read from the channel. This is true unless the channel buffer is full.

If a channel is full, the Go routine will wait for another Go routine to read from the channel before being able to put its own value there.

Unbuffered channel

An unbuffered channel will have no room to store any data. So in order for a value to be passed over an unbuffered channel, the sending Go routine will block until the receiving Go routine has received the value.

So, there is surely a difference between a buffered and an unbuffered channel. In the memory model case:

package main
import "fmt"

var c = make(chan int)
var a string

func f() {
    a = "hello, world"
    x := <- c
    fmt.Println(x)
}

func main() {
    go f()
    c <- 0
    print(a)
}

if you had a buffered channel var c = make(chan int, 1), the main() Go routine would just put a value in the buffer and then continue on with print(a), maybe before the f() Go routine has had time to set a to "hello, world".

But in the current code, the main Go routine will block at c <- 0, waiting for f() to receive the value before continuing with printing, and then we know for sure that a is already set to "hello, world".

PlaygroundLink-WithBuffer

PlaygroundLink-WithoutBuffer

like image 51
ANisus Avatar answered Sep 24 '22 21:09

ANisus


make(chan int) produces an unbuffered channel, make(chan int, 1) produces a channel with a buffer of 1.

See http://golang.org/doc/effective_go.html#channels for an explanation of the difference.

like image 38
Evan Avatar answered Sep 21 '22 21:09

Evan