Когда канал буферирован, это означает, что он не будет блокировать, пока буфер не будет заполнен. После того, как буфер будет заполнен, отправляющая goroutine будет блокироваться, когда он пытается добавить вещи в канал.
Это означает, что это заблокирует:
c := make(chan int)
c <- 1 // Block here, this is unbuffered !
println(<-c)
И это будет также блокировать:
c := make(chan int, 2)
c <- 1
c <- 2
c <- 3 // Block here, buffer is full !
println(<-c)
Но точка Goroutines и Channel именно для того, чтобы запустить вещи одновременно, так что это сработает:
c := make(chan int)
go func() { c <- 1; }() // This will block in the spawned goroutine until...
println(<-c) // ... this line is reached in the main goroutine
И аналогично:
c := make(chan int, 2)
go func() { // `go ...` spawns a goroutine
c <- 1 // Buffer is not full, no block
c <- 2 // Buffer is not full, no block
c <- 3 // Buffer is full, spawned goroutine is blocking until...
}()
println(<-c) // ... this line is reached in the main goroutine
В вашем примере вы порождаете четыре разных Goroutines, которые пишут четыре числа в один и тот же буферный канал. Поскольку буфер составляет 2 <16, они в конечном итоге блокируют
Но суть дела в том, что политика GO в Подождите, только основной Goroutine:
Выполнение программы начинается с инициализации основного пакета, а затем вызывая основную функцию. Когда основная функция возвращается, программа выходит. Это не ждет, пока другие (не-мэйн) goroutines завершится.
Это означает, что в вашем первом примере главный goroutine блокировался, когда он достиг линии c <- 3
. Анкет Поскольку ни один другой goroutine не смог сделать что -либо, что могло бы его сблокировать, то время выполнения обнаружило, что программа была запущена и сообщила об ошибке.
Однако во втором примере, однако, порождено Goroutines блокируется, в то время как основной продолжается тихо, пока не достигнет конца своего исполнения, после чего все (заблокированные) породились горутины, молча убит, и не сообщается об ошибках.