チャネルがバッファリングされると、これはバッファがいっぱいになるまでブロックしないことを意味します。バッファがいっぱいになると、送信ゴルウチンはチャネルに物を追加しようとするとブロックされます。
これは、これがブロックされることを意味します。
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)
しかし 点 ゴロウチンとチャネルの正確には、物事を同時に実行するためには、これは機能します。
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
あなたの例では、4つの異なるゴルチンを生成し、すべてが同じバッファーチャネルに4つの数字を書き込みます。バッファーが2 <16であるため、ブロックされます
しかし、問題の核心は、GOポリシーが メインゴルウチンだけを待ちます:
プログラムの実行は、メインパッケージを初期化し、関数メインを呼び出すことから始まります。関数メインが戻ると、プログラムは終了します。他の(非メインの)ゴルウチンが完了するのを待つことはありません。
これは、最初の例では、 主要 ゴルウチンは、ラインに到達したときにブロックしていました c <- 3
. 。他のGoroutineがブロックを解除できる可能性のあることは何でもできなかったため、ランタイムはプログラムがデッドロックされていることを検出し、エラーを報告しました。
ただし、2番目の例では、 生み出した ゴルチンはブロックされますが、メインは実行の終了に達するまで静かに続きます。