ホームページ  >  記事  >  バックエンド開発  >  Go チャネルがデッドロックを引き起こす理由と、それを防ぐにはどうすればよいですか?

Go チャネルがデッドロックを引き起こす理由と、それを防ぐにはどうすればよいですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-11-02 09:50:03394ブラウズ

Why Do Go Channels Cause Deadlocks and How Can We Prevent Them?

Go チャネルとデッドロック: ブロッキングの問題について

Go チャネルを使用する場合、適切な同期が確保されていないとデッドロックが発生する可能性があります。次の例を考えてみましょう。

<code class="go">func main() {
    c1 := make(chan int)
    c2 := make(chan int)

    // Create two goroutines that ping-pong values between channels
    go func() {
        for i := range c1 {
            println("G1 got", i)
            c2 <- i
        }
    }()

    go func() {
        for i := range c2 {
            println("G2 got", i)
            c1 <- i
        }
    }()

    // Send an initial value to start the chain
    c1 <- 1

    // Wait for a long time to observe the ping-ponging behavior
    time.Sleep(1000000000 * 50)
}</code>

このコードは、main 関数が終了するまで、値を無期限に正常に出力します。ただし、別の値がチャネルの 1 つに送信されると、デッドロックが発生します:

<code class="go">func main() {
    c1 := make(chan int)
    c2 := make(chan int)

    // Create two goroutines to ping-pong values between channels
    go func() {
        for i := range c1 {
            println("G1 got", i)
            c2 <- i
        }
    }()

    go func() {
        for i := range c2 {
            println("G2 got", i)
            c1 <- i
        }
    }()

    // Send an initial value to start the chain
    c1 <- 1

    // Wait for a short time
    time.Sleep(1000000000 * 1)

    // Send another value to the channel
    c1 <- 2

    // Wait for a long time to observe the issue
    time.Sleep(1000000000 * 50)
}</code>

この場合、値 "2" を送信した後に出力が停止します:

G1 got 1
G2 got 1
G1 got 1
G2 got 1
G1 got 2

この問題は、ゴルーチンがそれぞれのチャネルから値を受信するのをお互いに待機しているために発生します。したがって、どちらのゴルーチンも進行できず、デッドロックが発生します。

デッドロックを防ぐには、チャネルが適切に同期されていることを確認してください。 1 つのアプローチは、次の例のように、ゼロ以外の容量を持つバッファーされたチャネルを使用することです。

<code class="go">// ... (Same code as before)
c1 := make(chan int, 1) // Buffered channel with capacity of 1
c2 := make(chan int, 1)</code>

バッファーされたチャネルを使用すると、他のゴルーチンが前のゴルーチンをまだ受信していない場合でも、1 つのゴルーチンは値を送信できます。 1つ。これは、前述のような状況でのデッドロックを回避するのに役立ちます。

以上がGo チャネルがデッドロックを引き起こす理由と、それを防ぐにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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