「致命的なエラー: すべてのゴルーチンがスリープ状態です - デッドロック!」を理解するwith sync.WaitGroup
同時実行ゴルーチンを管理するために sync.WaitGroup パッケージを利用しようとする場合、恐ろしい「致命的エラー: すべてのゴルーチンがスリープ状態 - デッドロック!」を回避することが重要です。このエラーは、WaitGroup の誤った使用法、特に参照ではなくコピーによって値を渡す場合に発生します。
デッドロックの原因
この問題は、実際の WaitGroup オブジェクトを doWork 関数に渡すと、Go は値のコピーを作成します。これは、元の WaitGroup が、対応する Done() 呼び出しを行わずに、Add() 呼び出しを 10 回実行してカウンタをインクリメントしたことを意味します。対照的に、ゴルーチンに渡される WaitGroup の各コピーには、Done() 呼び出しが 1 つだけあり、WaitGroup がコピーされたときに存在していた数の Add() 呼び出しが含まれます。
解決策: 渡すWaitGroup
へのポインター このデッドロックを解決するには、WaitGroup
へのポインターを渡すことが不可欠です。 WaitGroup オブジェクト自体ではなく、WaitGroup。これにより、すべてのゴルーチンが同じ WaitGroup を参照するようになり、Done() を呼び出すと、減分カウンタが正しい 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{} for i := 0; i < 10; i++ { wg.Add(1) go doWork(wg) } wg.Wait() }
以下変更されたコードは、へのポインターの正しい使用法を示しています。 WaitGroup:
このアプローチを採用すると、WaitGroup でゴルーチンを自信を持って管理でき、デッドロックの落とし穴を回避し、効率的な同時実行を確保できます。以上が「致命的なエラー: すべてのゴルーチンがスリープ中です - デッドロック!」を回避する方法sync.WaitGroup を使用しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。