Go の同時実行におけるゴルーチンのデッドロックの解決
Go の同時実行プログラムでは、ゴルーチンが互いのリソースの解放を無期限に待機すると、デッドロックが発生する可能性があります。このようなデッドロックを解決するには、次の例を検討してください。
<code class="go">// Create a channel for communication between goroutines. ch := make(chan int) // Start producer goroutines that send values to the channel. go producer(ch, 100*time.Millisecond, 2) go producer(ch, 200*time.Millisecond, 5) // Indefinite loop to continuously receive values from the channel. for { fmt.Println(<-ch) }</code>
このコードでは、デッドロック エラーが発生します。「致命的なエラー: すべてのゴルーチンがスリープ状態です - デッドロック!」これは、プロデューサーの寿命が有限であり、最終的には送信を停止する一方、コンシューマーのゴルーチンは新しい値を際限なく待機するために発生します。このデッドロックを回避するには、次の 2 つの主な戦略を採用できます。
1.チャネルの終了:
チャネルは一度しか閉じることができないため、プロデューサーがコンシューマーに終了を通知することが不可欠です。コーディネーターはプロデューサーの完了を監視し、それに応じてチャネルを閉じることができます。
2.調整された同期:
sync.WaitGroup のような同期プリミティブを使用すると、プロデューサーは終了時にコーディネーターに通知でき、すべてのプロデューサーが終了したらコーディネーターはチャネルを閉じることができます。
同期を使用して更新されたコード:
<code class="go">import ( "fmt" "sync" "time" ) func producer(ch chan int, d time.Duration, num int, wg *sync.WaitGroup) { defer wg.Done() for i := 0; i < num; i++ { ch <- i time.Sleep(d) } } func main() { // Create a WaitGroup for coordinating producer completion. wg := &sync.WaitGroup{} // Initialize the channel for communication between goroutines. ch := make(chan int) // Start producer goroutines. wg.Add(2) go producer(ch, 100*time.Millisecond, 2, wg) go producer(ch, 200*time.Millisecond, 5, wg) // Assign a goroutine to close the channel when all producers have finished. go func() { wg.Wait() close(ch) }() // Iterate over values from the channel until it's closed. for v := range ch { fmt.Println(v) } }</code>
結論:
チャネル終了または調整された同期のいずれかを実装することで、開発者はゴルーチンのデッドロックを効果的に回避でき、同時実行の Go プログラムで適切な調整を確保します。
以上が## 同時実行 Go プログラムでのデッドロックを回避するには?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。