WaitGroup 構造体を値で渡すと Go チャネル通信でデッドロックが発生するのはなぜですか?

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

Why Does Passing a WaitGroup Structure by Value Cause a Deadlock in Go Channel Communication?

値による構造の受け渡しによる Go チャネル通信のデッドロック

コード内で、ゴルーチン チャネルでデッドロック エラーが発生しましたコミュニケーション。このエラーは、WaitGroup 構造体を値によってゴルーチンに渡しているため、元の参照を共有する代わりに WaitGroup のコピーが作成されることが原因です。

値による受け渡しがデッドロックを引き起こす理由

Go の構造体は、参照ではなく値によって渡されます。構造体を関数に渡すと、コピーが作成されて関数に渡されます。これは、関数内の構造に加えられた変更は、関数の外側の元の構造には反映されないことを意味します。

あなたの場合、ゴルーチンはタスクの完了時に WaitGroup に信号を送ろうとしています。ただし、WaitGroup のコピーを使用しているため、Done() 呼び出しは元の WaitGroup には影響しません。その結果、メインの goroutine の Wait() 呼び出しが完了せず、デッドロックが発生します。

解決策: ポインターによる受け渡し

この問題を解決するには、次のようにします。 WaitGroup をポインタによってゴルーチンに渡す必要があります。これにより、ゴルーチンとメインのゴルーチンの両方が WaitGroup への同じ参照を共有するようになります。

作業例:

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

<code class="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()
}</code>
ログイン後にコピー

これで、このコードを実行すると、デッドロック エラーが発生しなくなります。 goroutine は WaitGroup に正常に信号を送り、メインの goroutine はその実行を完了できるようになります。

以上がWaitGroup 構造体を値で渡すと Go チャネル通信でデッドロックが発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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