WaitGroup を使用したバッファーされたチャネルの空の待機
同時プログラミングでは、多くの場合、同時に実行するゴルーチンの数を制御する必要があります。一般的なアプローチは、バッファリングされたチャネルをセマフォとして使用することです。ただし、このアプローチの制限に注意することが重要です。
次の例を考えてみましょう:
ints := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} sem := make(chan struct{}, 2) for _, i := range ints { sem<- struct{}{} go func(id int, sem chan struct{}) { // do something <-sem }(i, sem) }
このコードは、サイズ 2 のバッファー チャネル (sem) を使用して、同時接続数を制限しています。ただし、問題があります。最後のいくつかのゴルーチンがタスクを完了する前にプログラムが終了する可能性があります。これは、プログラムがさらにゴルーチンをディスパッチしている間であっても、処理中のどの時点でもバッファリングされたチャネルが空になる可能性があるためです。
バッファリングされたチャネルが空になるのを待つために、チャネル自体に依存することはできません。代わりに、sync.WaitGroup を使用して、未処理の goroutine の数を追跡できます。
sem := make(chan struct{}, 2) var wg sync.WaitGroup for _, i := range ints { wg.Add(1) sem<- struct{}{} go func(id int) { defer wg.Done() // do something <-sem }(i) } wg.Wait()
この変更されたコードでは、wg.Add(1) を使用して、各 goroutine をディスパッチする前に待機グループをインクリメントします。 defer wg.Done() ステートメントは、ゴルーチンがタスクを完了したときに待機グループをデクリメントします。最後に、wg.Wait() は待機グループが 0 に達するまでブロックし、すべてのゴルーチンの実行が確実に終了します。このアプローチにより、チャネルが空になるのを待つことができ、プログラムが途中で終了することがなくなります。
以上がバッファーされたチャネルをセマフォとして使用する場合、すべてのゴルーチンが確実に終了するようにするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。