sync.WaitGroup を使用して複数のゴルーチンの完了を調整しようとする場合、「致命的なエラー: すべてのゴルーチンがスリープ状態です - デッドロック!」というエラーが発生する可能性があります。この不可解なメッセージは、特にコードがドキュメントの例に従って記述されているように見える場合に、不可解になる可能性があります。
このエラーの原因は、Go が関数に渡される値を処理する方法にあります。 sync.WaitGroup オブジェクトを直接渡す場合、Go はその値のコピーを作成し、基本的には異なるオブジェクトを各 goroutine に渡します。これにより、元の WaitGroup とゴルーチンが動作するコピーとの間に切断が作成されます。
この問題の解決策は、代わりに sync.WaitGroup へのポインターを渡すことです。そうすることで、すべてのゴルーチンが同じ基礎となるオブジェクトを参照し、その内部カウンターで一貫して動作するようになります。ポインターを使用した正しいコードを以下に示します。
import "sync" func doWork(wg *sync.WaitGroup) error { defer wg.Done() // Do some heavy lifting... request URL's or similar return nil } func main() { wg := &sync.WaitGroup{} // Use pointer to pass the WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go doWork(wg) } }
この変更により、ゴルーチンは WaitGroup オブジェクトと適切に対話し、作業を開始する前にカウンターをインクリメントし、完了時にカウンターをデクリメントします。その結果、メイン関数の WaitGroup.Wait() 呼び出しが無期限にブロックされることはなく、プログラムは期待どおりに実行されます。
以上が`sync.WaitGroup` を使用すると「致命的なエラー: すべてのゴルーチンがスリープ状態になっています - デッドロック!」が発生するのはなぜですか? どうすれば修正できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。