ホームページ  >  記事  >  バックエンド開発  >  外部関数で sync.WaitGroup を使用するとデッドロックが発生するのはなぜですか?

外部関数で sync.WaitGroup を使用するとデッドロックが発生するのはなぜですか?

DDD
DDDオリジナル
2024-11-06 19:43:02643ブラウズ

Why Does Using sync.WaitGroup with External Functions Lead to Deadlock?

外部関数での sync.WaitGroup の使用

プログラム内で、main 関数の外部で定義された関数で sync.WaitGroup を使用すると、問題が発生する可能性があります。この状況を調べてみましょう。

問題:

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

<code class="go">package main

import (
    "fmt"
    "sync"
)

func main() {
    ch := make(chan int)
    var wg sync.WaitGroup
    wg.Add(2)
    go Print(ch, wg) //
    go func(){

        for i := 1; i <= 11; i++ {
            ch <- i
        }

        close(ch)
        defer wg.Done()
    }()

    wg.Wait() //deadlock here
}

// Print prints all numbers sent on the channel.
// The function returns when the channel is closed.
func Print(ch <-chan int, wg sync.WaitGroup) {
    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }
    defer wg.Done()
}</code>

ここでは、プログラムが数値を出力することを目的としています。 1 ~ 11 ですが、場合によっては 1 ~ 10 しか出力されません。

エラー分析:

sync.WaitGroup のコピーを Print 関数に渡しています。これは、メイン関数で待機している sync.WaitGroup の Done() メソッドを呼び出さないことを意味します。

解決策:

この問題を解決するには

<code class="go">package main

import (
    "fmt"
    "sync"
)

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

    var wg sync.WaitGroup
    wg.Add(2)

    go Print(ch, &wg)

    go func() {
        for i := 1; i <= 11; i++ {
            ch <- i
        }
        close(ch)
        defer wg.Done()
    }()

    wg.Wait() //deadlock here
}

func Print(ch <-chan int, wg *sync.WaitGroup) {
    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }
    defer wg.Done()
}</code>

これにより、Print 関数が main 関数で待機しているのと同じ sync.WaitGroup の Done() メソッドを呼び出すようになります。

あるいは、コードを再構築して、Print 関数の sync.WaitGroup への依存を削除することもできます。

<code class="go">package main

import (
    "fmt"
)

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

    go func() {
        for i := 1; i <= 11; i++ {
            ch <- i
        }
        close(ch)
    }()

    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }
}</code>

以上が外部関数で sync.WaitGroup を使用するとデッドロックが発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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