WaitGroup デッドロック: 「すべてのゴルーチンがスリープ状態 - デッドロック!」を理解する
WaitGroup を使用してゴルーチンを調整しようとすると、次のような問題が発生する可能性があります。エラー「致命的エラー: すべてのゴルーチンがスリープ中 - デッドロック!」。これは、WaitGroup のカウンターをデクリメントするゴルーチンが誤ってスリープ状態になった場合に発生します。
問題:
次の Go コードは、このエラーがどのように発生するかを示しています。
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() fmt.Println("Hello", i) }() } wg.Wait() }
実行すると、このコードはそれぞれに対して「Hello」を出力するはずです。ゴルーチン。ただし、代わりに、プログラムは恐ろしい「デッドロック」エラーで終了します。
理由:
問題は、WaitGroup がゴルーチンに渡される方法にあります。 Go は、値が匿名関数に渡されるときに、その値のコピーを作成します。したがって、各ゴルーチンは WaitGroup の個別のコピーで動作し、いずれのゴルーチンもカウンタをデクリメントしないため、ゴルーチンは永続的にスリープ状態になります。
解決策:
デッドロックを解決するには、WaitGroup 自体ではなく、WaitGroup へのポインタを渡す必要があります。したがって、すべてのゴルーチンは同じ WaitGroup を参照し、そのカウンタを正しくデクリメントできるようになります。
package main import ( "fmt" "sync" ) func main() { wg := &sync.WaitGroup{} for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() fmt.Println("Hello", i) }() } wg.Wait() }
ポインタを渡すことにより、ゴルーチンは同じ WaitGroup オブジェクトを共有し、実行を正常に調整できます。このバージョンのコードは、デッドロックを引き起こすことなく、各 goroutine に対して「Hello」を正しく出力します。
以上がGo WaitGroup によって「すべての Goroutines Are Aleep - Deadlock!」が発生するのはなぜですか?エラー?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。