ホームページ > バックエンド開発 > Golang > Goroutine と Channel を使用するときに Golang でデッドロックを防ぐ方法は?

Goroutine と Channel を使用するときに Golang でデッドロックを防ぐ方法は?

Susan Sarandon
リリース: 2024-10-27 06:48:29
オリジナル
531 人が閲覧しました

How to Prevent Deadlock in Golang When Using Goroutines and Channels?

ゴルーチンのデッドロックの解決

同時 Golang プログラムを使用している場合、デッドロック エラーが発生する可能性があります。「致命的なエラー: すべてのゴルーチンがスリープ状態です -行き詰まり!」。このエラーは、複数のゴルーチンがタスクの実行を互いに待機しており、デッドロック状況が生じている場合に発生します。

次のコードを考えてみましょう:

<code class="go">func producer(ch chan int, d time.Duration, num int) {
    for i := 0; i < num; i++ {
        ch <- i
        time.Sleep(d)
    }
}

func main() {
    ch := make(chan int)

    go producer(ch, 100*time.Millisecond, 2)
    go producer(ch, 200*time.Millisecond, 5)

    for {
        fmt.Println(<-ch)    
    }

    close(ch)
}</code>
ログイン後にコピー

このコードは、値を送信する 2 つのプロデューサー ゴルーチンを作成します。同じチャンネルに。メインのゴルーチンは、無限ループでチャネルから値を継続的に受信します。

この問題は、プロデューサーが「短命」であり、有限時間が経過すると値の送信を停止するために発生しますが、メインのゴルーチンは値を受信し続けます。際限なく。これ以上値が送信されないことを示すためにチャネルが閉じられることがないため、デッドロックが発生します。

このデッドロックを解決するには、すべてのプロデューサーがタスクを完了したときにチャネルが閉じられるようにする必要があります。これを効率的に実現する方法は、sync.WaitGroup のような同期プリミティブを使用することです。

コードの修正版を次に示します。

<code class="go">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() {
    wg := &sync.WaitGroup{}
    ch := make(chan int)

    wg.Add(1)
    go producer(ch, 100*time.Millisecond, 2, wg)
    wg.Add(1)
    go producer(ch, 200*time.Millisecond, 5, wg)

    go func() {
        wg.Wait()
        close(ch)
    }()

    for v := range ch {
        fmt.Println(v)
    }
}</code>
ログイン後にコピー

このコードでは、同期を渡します。各プロデューサーのゴルーチンへの WaitGroup。各プロデューサーは開始前に待機グループをインクリメントし、終了時にデクリメントします。メインのゴルーチンは、wg.Wait() を使用してすべてのプロデューサーの完了を待ちます。すべてのプロデューサーが終了すると、メインの goroutine がチャネルを閉じます。

このソリューションにより、すべてのプロデューサーが作業を完了した後にのみチャネルが閉じられるようになり、デッドロック状況が回避されます。

以上がGoroutine と Channel を使用するときに Golang でデッドロックを防ぐ方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート