ホームページ > バックエンド開発 > Golang > Go チャネルでデッドロックがどのように発生するのか、またそのデバッグ方法は?

Go チャネルでデッドロックがどのように発生するのか、またそのデバッグ方法は?

Patricia Arquette
リリース: 2024-10-30 15:16:02
オリジナル
737 人が閲覧しました

How Can Deadlocks Occur in Go Channels and How to Debug Them?

Go チャネルとデッドロック

Go では、ゴルーチン間の通信にチャネルが使用されます。ただし、チャネルが適切に処理されない場合、デッドロックが発生する可能性があります。

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

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

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

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

  c1 <- 1

  time.Sleep(1000000000 * 50)
}</code>
ログイン後にコピー

このコードは、main 関数が終了するまで無限に数値を出力します。ただし、メイン関数からチャネルの 1 つに別の値を送信すると、プログラムはブロックします:

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

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

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

  c1 <- 1

  time.Sleep(1000000000 * 1)

  c1 <- 2

  time.Sleep(1000000000 * 50)
}</code>
ログイン後にコピー

これは、2 番目のゴルーチンが c1 に送信された値 "2" を受信しないために発生します。このデッドロックの理由は、2 つのゴルーチンがお互いに値の送受信を待機しており、循環依存関係が作成されていることです。

デッドロックのデバッグ

デッドロックをデバッグするには、いくつかのアプローチを使用できます。

  • Unix 系 OS: kill -6 [pid] コマンドを使用してプログラムを強制終了し、各ゴルーチンのスタック トレースを出力します。
  • gdb: gdb をプロセスにアタッチし、アクティブな goroutine のスタックと変数を調べます。

以上がGo チャネルでデッドロックがどのように発生するのか、またそのデバッグ方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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