ホームページ > バックエンド開発 > Golang > 同じゴルーチン内のバッファリングされていないチャネルで送受信すると Go でデッドロックが発生するのはなぜですか?

同じゴルーチン内のバッファリングされていないチャネルで送受信すると Go でデッドロックが発生するのはなぜですか?

Mary-Kate Olsen
リリース: 2024-12-23 01:20:15
オリジナル
965 人が閲覧しました

Why Does Sending and Receiving on an Unbuffered Channel in the Same Goroutine Cause a Deadlock in Go?

同時実行 Go のデッドロックを理解する: ゴルーチン内のバッファリングされていないチャネル

Go の同時実行モデルでは、チャネルはゴルーチン間の通信に重要なツールです。ただし、次のコード スニペットに示すように、チャネルを不適切に使用するとデッドロックが発生する可能性があります:

package main

import "fmt"

func main() {
    c := make(chan int)  
    c <- 1   
    fmt.Println(<-c)
}
ログイン後にコピー

このコードを実行すると、次のエラー メッセージが表示されてデッドロックが発生します:

fatal error: all goroutines are asleep - deadlock!
ログイン後にコピー

このデッドロックはなぜ発生しますか?

問題は、バッファリングされていないメソッドの使用にあります。同じゴルーチン内のチャネル。バッファーなしチャネルには内部ストレージがありません。つまり、バッファーなしチャネルへの値の送信は、別のゴルーチンが値を読み取るまでブロックされます。

この場合、ゴルーチンはチャネル c に値を送信し、チャネル c から値を受信しようとします。同じチャンネルを連続して再生します。値を受け取る他の goroutine がないため、送信側の goroutine が無期限にハングし、デッドロックが発生します。

どうすれば修正できますか?

解決策は 2 つあります。 :

  1. バッファリングされたファイルを作成しますchannel: バッファーを使用してチャネルを作成すると、送信側のゴルーチンをブロックする前に複数の値を保存できるようになります。例:
c := make(chan int, 1) 
ログイン後にコピー

これにより、バッファ サイズ 1 のチャネルが作成され、ブロックせずに 1 つの値を格納できるようになります。

  1. 別の値を使用します。送信用の goroutine: 同じ goroutine 内で送信する代わりに、チャネルに値を送信するための別の goroutine を作成します。例:
package main

import "fmt"

func main() {
    c := make(chan int)    
    go func() {
        c <- 1
    }()
    fmt.Println(<-c)
}
ログイン後にコピー

この例では、送信側ゴルーチンはチャネル c に値を非同期で送信します。その後、メインの goroutine は、デッドロックが発生することなくチャネルから値を受け取ります。

バッファリングされていないチャネルの動作を理解し、不適切な使用を回避することは、効率的でノンブロッキングの同時実行 Go プログラムを作成するために重要です。

以上が同じゴルーチン内のバッファリングされていないチャネルで送受信すると Go でデッドロックが発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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