ホームページ  >  記事  >  バックエンド開発  >  ## 同時実行 Go プログラムでのデッドロックを回避するには?

## 同時実行 Go プログラムでのデッドロックを回避するには?

Susan Sarandon
Susan Sarandonオリジナル
2024-10-25 09:00:29677ブラウズ

## How to Avoid Deadlocks in Concurrent Go Programs?

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。