ホームページ > バックエンド開発 > Golang > sync.WaitGroup 使用時の Go チャネルのデッドロック エラーを修正する方法

sync.WaitGroup 使用時の Go チャネルのデッドロック エラーを修正する方法

Patricia Arquette
リリース: 2024-10-29 02:36:02
オリジナル
475 人が閲覧しました

How to Fix Deadlock Errors in Go Channels When Using sync.WaitGroup?

Go チャネルのデッドロック エラーについて

この記事では、「デッドロック!」の背後にある原因を分析します。次のコード スニペットの Go チャネルに関係するデッドロック状況から発生するエラー:

package main

import (
    "fmt"
    "sync"
)

func push(c chan int, wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int, wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result, ok := <-c
        fmt.Println(result, ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c, wg)
    go pull(c, wg)

    wg.Wait()
}
ログイン後にコピー

このコードを実行すると、次のエラーが発生します:

throw: all goroutines are asleep - deadlock!
ログイン後にコピー

デッドロックについて

このコードの sync.WaitGroup などの構造体が参照ではなく値で渡されるため、デッドロックが発生します。これは、WaitGroup を関数 (プッシュおよびプル) に渡すとき、実際には元のオブジェクトではなく WaitGroup のコピーを渡していることを意味します。

結果として、各関数は独自のコピーで動作することになります。 WaitGroup のコピーを作成し、wg.Done() を呼び出すと、自分自身のコピーがデクリメントされます。これにより、メインの goroutine が待機している元の WaitGroup が更新されないため、デッドロックが発生します。

デッドロックの修正

この問題を解決するには、ポインタを渡す必要があります。値の代わりに WaitGroup に設定します。これにより、プッシュ関数とプル関数の両方が WaitGroup の同じインスタンス上で動作し、wg.Done() への呼び出しが元のオブジェクトに影響を与えるようになります。

コードの修正バージョンは次のとおりです。

package main

import (
    "fmt"
    "sync"
)

func push(c chan int, wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int, wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result, ok := <-c
        fmt.Println(result, ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c, &wg)
    go pull(c, &wg)

    wg.Wait()
}
ログイン後にコピー

この変更を行うことで、WaitGroup へのポインターを関数に渡し、両方の関数が同じオブジェクト上で動作し、その状態を正しく更新できるようになります。これによりデッドロック状況が解消され、プログラムがエラーなく実行できるようになります。

以上がsync.WaitGroup 使用時の Go チャネルのデッドロック エラーを修正する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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