ホームページ > バックエンド開発 > Golang > Go でバッファなしチャネルを使用するとデッドロックが発生するのはなぜですか?

Go でバッファなしチャネルを使用するとデッドロックが発生するのはなぜですか?

Mary-Kate Olsen
リリース: 2024-12-18 16:55:10
オリジナル
318 人が閲覧しました

Why Does Using Unbuffered Channels in Go Lead to Deadlock?

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!

goroutine 1 [chan send]:
main.main()
    /path/to/file:8 +0x52
exit status 2
ログイン後にコピー

説明

デッドロックは、バッファリングされていないチャネルの使用が原因で発生します。ドキュメントに記載されているように、バッファなしチャネルでは、値を送信する前に受信者の存在が必要です。この場合、チャネルはデフォルトでバッファなし (バッファ サイズ 0) として初期化されます。

行 c

同時に、fmt.Println(<-c) ステートメントはチャネルから値を受信しようとします。ただし、まだ値が送信されていないため (ゴルーチンが受信者を待っているため)、受信操作はブロックされます。

両方のゴルーチンが他方のゴルーチンが操作を完了するのを待っているため、デッドロックが発生します。

解決策

デッドロックを解決するには、チャンネルの受信機。送信された値の受信を処理する別のゴルーチンを作成することで、デッドロックを解消できます。以下の変更されたコードは、この解決策を示しています:

package main

import "fmt"

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

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

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