ホームページ > バックエンド開発 > Golang > Go WaitGroup によって「すべての Goroutines Are Aleep - Deadlock!」が発生するのはなぜですか?エラー?

Go WaitGroup によって「すべての Goroutines Are Aleep - Deadlock!」が発生するのはなぜですか?エラー?

Barbara Streisand
リリース: 2024-12-25 19:14:17
オリジナル
755 人が閲覧しました

Why Does My Go WaitGroup Cause a

WaitGroup デッドロック: 「すべてのゴルーチンがスリープ状態 - デッドロック!」を理解する

WaitGroup を使用してゴルーチンを調整しようとすると、次のような問題が発生する可能性があります。エラー「致命的エラー: すべてのゴルーチンがスリープ中 - デッドロック!」。これは、WaitGroup のカウンターをデクリメントするゴルーチンが誤ってスリープ状態になった場合に発生します。

問題:

次の Go コードは、このエラーがどのように発生するかを示しています。

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            fmt.Println("Hello", i)
        }()
    }
    wg.Wait()
}
ログイン後にコピー

実行すると、このコードはそれぞれに対して「Hello」を出力するはずです。ゴルーチン。ただし、代わりに、プログラムは恐ろしい「デッドロック」エラーで終了します。

理由:

問題は、WaitGroup がゴルーチンに渡される方法にあります。 Go は、値が匿名関数に渡されるときに、その値のコピーを作成します。したがって、各ゴルーチンは WaitGroup の個別のコピーで動作し、いずれのゴルーチンもカウンタをデクリメントしないため、ゴルーチンは永続的にスリープ状態になります。

解決策:

デッドロックを解決するには、WaitGroup 自体ではなく、WaitGroup へのポインタを渡す必要があります。したがって、すべてのゴルーチンは同じ WaitGroup を参照し、そのカウンタを正しくデクリメントできるようになります。

package main

import (
    "fmt"
    "sync"
)

func main() {
    wg := &sync.WaitGroup{}
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            fmt.Println("Hello", i)
        }()
    }
    wg.Wait()
}
ログイン後にコピー

ポインタを渡すことにより、ゴルーチンは同じ WaitGroup オブジェクトを共有し、実行を正常に調整できます。このバージョンのコードは、デッドロックを引き起こすことなく、各 goroutine に対して「Hello」を正しく出力します。

以上がGo WaitGroup によって「すべての Goroutines Are Aleep - Deadlock!」が発生するのはなぜですか?エラー?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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