2017-04-08 17 views
1

行き先2番目のgoroutineをコメントアウトすると、致命的なエラーが発生します。私はこのエラーの原因を理解していません。それを私に説明できますか?送信ゴルーチンからすべての値を受信した後chから受信にループブロックのゴルーチン間のデッドロック

0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
fatal error: all goroutines are asleep - deadlock! 

goroutine 1 [chan receive]: 
main.main() 
    /tmp/sandbox169127128/main.go:17 +0xa0 

Program exited. 

答えて

5

受信:

package main 

import (
    "fmt" 
    "time" 
) 

func main() { 
    ch := make(chan int) 
    go func() { 
     for i := 0; i < 10; i++ { 
      ch <- i 
     } 
    }() 
    // go func() { 
     for { 
      if num, ok := <-ch; !ok { 
       break 
      } else { 
       fmt.Printf("%d\n", num) 
      } 
     } 
    // }() 
    time.Sleep(2 * time.Second) 
    close(ch) 
} 

これは、次のコードを印刷します。ランタイムは、プログラムが停止してパニックすることを検出します。

修正はすべての値を送信した後にチャンネルを閉じることである。

go func() { 
    for i := 0; i < 10; i++ { 
     ch <- i 
    } 
    close(ch) 
}() 

は、閉じたチャネルで受信は値0, falseを生み出します。受信forループは、false値でブレークします。

プログラムの最後からclose(ch)を削除します。

Run it on the playground

+0

は簡潔な説明、セリーズいただきありがとうございます。私は「ブロッキング」のアイデアを完全に理解しているかどうかはわかりません。 これは、受信forループが永久に待機していることを意味しますか?これは、下のコードの左側にあるokがtrueを受け取るためですが、他にnumを与えることはありませんか? if num、ok:= <-ch; !ok – Pizzas

+0

@Pizzas:https://en.wikipedia.org/wiki/Blocking_(computing)あなたのケースでは、 'num、ok:= <-ch'はブロックしています(別の応答を待っています)。それ以外の応答は決して来ていません。送信ルーチンが既に終了しているからです。送信中のルーチンでチャネルを閉じると、別の応答(チャネルが閉じていることを示す)_が受信されます。 – Flimzy

+0

@Pizzasオープンチャネルで受信すると、チャネルに値が送信されるのを待ちます。受信ループは、送信側のゴルーチンからのすべての値が受信された後、永久に待機します。 –

2

最初のゴルーチンが終了する前にチャンネルを終了していないためです。以下のコードは動作するはずです。

package main 

import (
    "fmt" 
    "time" 
) 

func main() { 
    ch := make(chan int) 
    go func() { 
     for i := 0; i < 10; i++ { 
      ch <- i 
     } 
     close(ch) 
    }() 
    //go func() { 
     for { 
      if num, ok := <-ch; !ok { 
       break 
      } else { 
       fmt.Printf("%d\n", num) 
      } 
     } 
    //}() 
    time.Sleep(2 * time.Second) 
} 

ここでそれを試してみてください:https://play.golang.org/p/OdxNqbaZmj

関連する問題