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

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

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-18 16:55:10320ブラウズ

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

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