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?

- 42,244
- 6
- 132
- 114

- 115
- 1
- 6
-
Very similar: http://stackoverflow.com/questions/20041392/how-does-makechan-bool-behave-differently-from-makechan-bool-1 – Matt Apr 24 '14 at 13:14
3 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"
.
-
When you say: *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*. So, the *`put` Goroutine* & *`get` Goroutine* has simultaneous access to single buffered channel. Channel is a queue. Does these two Goroutines require synchronization mechanism to access buffered channel? – overexchange Apr 08 '19 at 14:14
-
@overexchange Sending and receiving can be done on a channel by multiple goroutines without further synchronization. See last paragraph: https://golang.org/ref/spec#Channel_types – ANisus Apr 10 '19 at 18:50
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.

- 6,369
- 1
- 29
- 30
The first creates an unbuffered channel, while the second creates a buffered channel.
You can see the difference when trying to send a value on the channel:
c <- 1
In the case of an unbuffered channel, this statement will block until a corresponding receive operation on the channel occurs (i.e. <-c
). In the case of a buffered channel, the send can complete without blocking if there is space to store the value in the channel's buffer.
In most cases, unbuffered channels are suitable and have the benefit that they'll quickly show up any concurrency problems due to their blocking nature. There are certain cases where a buffer makes sense though.
As far as the Go memory model goes, the same "happens before" relationship is true for both buffered and unbuffered channels. While the send operation doesn't block for a corresponding receive with a buffered channel, code that runs after the receive are still guaranteed to "happen after" code that ran before the send.

- 42,244
- 6
- 132
- 114
-
I'd add my 'rule of thumb', which is to develop code without buffering, then add it later to improve performance. If the unbuffered code never deadlocks, then the buffered code won't either, but it might run faster. – Rick-777 Apr 23 '14 at 08:44