モジュールのレッスン (2/5)
チャネル: 型付きコミュニケーション
チャネルは、次の間の通信のための慣用的なメカニズムです。 ゴルーチン。囲碁の哲学 (ロブ・パイク):
「記憶を共有することでコミュニケーションするのではなく、コミュニケーションすることで記憶を共有する。」
チャネルは 型指定された FIFO キューであり、タイプセーフで同時実行も安全です。
使用します。 go と組み合わせると、Go の主要な構成要素になります。
同時並行性。
作成、送信、受信
ch := make(chan int) // canale di int, unbuffered
go func() {
ch <- 42 // invia (può bloccare)
}()
v := <-ch // ricevi (può bloccare)
fmt.Println(v) // 42構文:
- バッファリングの場合は
make(chan T)またはmake(chan T, N)。 ch <- vが送信します。v := <-chが受信します。v, ok := <-chはフラグ付きで受信します (チャンネルが閉じていて空の場合はok = false)。
バッファなし: ランデブー
バッファなしチャネル (容量 0) は以下をブロックします。
- 受信者の準備が整うまで、送信者。
- 送信者の準備が整うまで、受信者。
これは同期的な予定です。「合図」として、または保証するために役立ちます。 価値が提供されたことを意味します。
バッファリング: 最大 N 個のキュー
ch := make(chan int, 3)
ch <- 1 // non blocca
ch <- 2 // non blocca
ch <- 3 // non blocca
ch <- 4 // BLOCCA: il buffer è pieno送信者は、バッファがいっぱいの場合にのみブロックします。受信機のみ 空のとき。
近距離および遠距離向け
送信者は、値がなくなるとチャネルを閉じます。
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)
for v := range ch { // termina quando ch è chiuso E vuoto
fmt.Println(v)
}チャネル上の for range は、チャネルが閉じられる (そして排出される) まで繰り返されます。
「届いたものはすべて消費する」という最もきれいなパターンです。
サインの方向性
関数パラメータは方向を制限できます。
func producer(out chan<- int) { // solo invio
out <- 1
close(out)
}
func consumer(in <-chan int) { // solo ricezione
for v := range in {
fmt.Println(v)
}
}chan<- T = 送信専用、<-chan T = 受信専用。双方向
チャネル chan T はどちらにも渡すことができます (暗黙的な変換)。それ
明瞭さが向上し、間違いが防止されます。
よくあるパターン(プレビュー)
- ワーカー プール: N 個のゴルーチンが
jobs <-chan Tから消費され、results chan<- Rに生成されます。 - パイプライン: チャネルによって接続されたステージ。
- 完了信号:
chan struct{}チャネルが閉じられ、「停止」信号が送信されます。
done := make(chan struct{})
go func() {
<-done // blocca finché qualcuno chiude done
cleanup()
}()
close(done) // segnale di stopchan struct{} は「信号」チャネルです。ペイロードはゼロバイトで、
同期。
試してみてください
unbuffered int チャネル ch を作成し、ゴルーチンから 42 を送信し、main で受信して出力します。
ヒントを表示
バッファがなければ、送信者と受信者は同期します。
3 回の試行後に解決策が利用可能になります
バッファリングされたチャネル経由で 1、2、3 を送信し、チャネルを閉じてから、すべてを for-range で出力します。
ヒントを表示
チャネル上の「範囲用」は、チャネルが閉じられて排水されると終了します。
3 回の試行後に解決策が利用可能になります
送信者が送信したが受信者の準備ができていない場合、UNBUFFERED チャネルは何をしますか?
ch := make(chan int)
ch <- 1 // ?要約
- チャネル = 型付き FIFO キュー、ゴルーチン間では安全です。
- バッファなし: ランデブー (送信者と受信者が同期)。
- バッファリング: デカップリング、フル/空の場合のみブロック。
close(ch): 送信者のみ。for rangeは閉じるまで消費されます。- 方向性:
chan<- T(送信のみ)、<-chan T(受信のみ)。 - 純粋な同期のための信号チャネルとしての
chan struct{}。