ゴルーチンは、同時プログラミングのための Go の基本的な概念です。メインスレッドをブロックすることなく、複数のタスクを同時に実行できます。ただし、ゴルーチンの使用は、特に複数のゴルーチンから結果を収集する場合に注意が必要です。
問題ステートメント
開発者は、ゴルーチンを使用して次のゴルーチンのリストを処理しようとしました。項目を作成し、処理された値をスライスに収集します。しかし、彼らは恐ろしい「すべてのゴルーチンが眠っている - デッドロック!」に遭遇しました。 error.
デッドロックの根本原因
コードが結果を収集する前にすべての goroutine の処理が完了するのを待っていたため、デッドロックが発生しました。これにより、ゴルーチンがスライスへの書き込みが可能になるのを待機している一方で、メインスレッドはゴルーチンの処理が完了するのを待機しているという状況が発生しました。
解決策
デッドロックを解決するには、ゴルーチンとメインスレッド間の通信に使用されるチャネルの非同期クローズを導入する必要があります。以下の変更されたコードは、解決策を示しています。
// ... // Create a channel to receive the processed values sampleChan := make(chan sample) var wg sync.WaitGroup // Process each item in the list with a goroutine for i, line := range contents { wg.Add(1) go func(line string) { defer wg.Done() // Process the item and send the result on the channel sampleChan <- newSample(line, *replicatePtr, *timePtr) }(line) } // Asyncronously close the channel when all goroutines are done go func() { wg.Wait() close(sampleChan) }() // Read from the channel and gather results into a slice var sampleList []sample for s := range sampleChan { sampleList = append(sampleList, s) } // ...
チャネルを非同期で閉じることにより、ゴルーチンの処理中であっても、メインスレッドは結果の収集を続行できます。これにより、デッドロックが解消され、コードが正しく実行できるようになります。
追加の考慮事項
この解決策はデッドロックを解決しますが、完全な解決策ではないことに注意してください。この特定のシナリオで同時実行を管理するためのものです。要件とゴルーチンの数に応じて、コードの信頼性と正確性を確保するために追加の同期およびエラー処理メカニズムが必要になる場合があります。
以上がGo でゴルーチンから結果を収集するときにデッドロックを回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。