閉じたチャネルからの値の受信が可能な理由
Go では、チャネルはゴルーチン間の通信メカニズムを提供します。チャネルが閉じられると、それ以上値が送信されないことを示します。ただし、チャネルのバッファ内の既存の値がすぐに破棄されるという意味ではありません。
仕様では、チャネルを閉じた後、ゼロ値を受信する前に、以前に送信された値を引き続き受信できると規定されています。これは、チャネルのバッファがキューとして機能し、閉じる操作の前に送信された値を保存するためです。
仕組み:
次のコードを考えてみましょう:
package main import "fmt" import "sync" import "time" func main() { iCh := make(chan int, 99) var wg sync.WaitGroup go func() { for i := 0; i < 5; i++ { wg.Add(1) go func(i int) { defer wg.Done() iCh <- i }(i) } wg.Wait() close(iCh) }() time.Sleep(5 * time.Second) for i := range iCh { fmt.Printf("%v\n", i) } }
出力:
0 1 2 3 4
5時以降にチャンネルが閉じられても秒後、for ループはクローズ操作前に送信された 5 つの値を引き続き受け取ります。これは、チャネル バッファーがこれらの値を消費されるまで保存するためです。
以前に送信された値をすべて受信した後でのみ、for ループはゼロ値を返し、チャネルが閉じられていることを示します。
「Time.Sleep」トリックが失敗する理由:
「time.Sleep」トリックは、ゴルーチンの送信の継続を妨げません。チャネルを閉じる前に値をチャネルに追加します。ゴルーチンが 5 秒間スリープしている間、バッファリングされて for ループによって受信される追加の値を送信している可能性があります。
以上がクローズされた Go チャネルから値を受信できるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。