ホームページ  >  記事  >  バックエンド開発  >  WaitGroup 構造体を値で渡すと Go チャネル通信でデッドロックが発生するのはなぜですか?

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

Patricia Arquette
Patricia Arquetteオリジナル
2024-10-29 07:47:02395ブラウズ

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

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