2016-10-11 7 views
0

私はここに同時実行の例で午前:https://tour.golang.org/concurrency/5この並行処理の例では何が起こっていますか?

は、これはコードです:

package main 

import "fmt" 

func fibonacci(c, quit chan int) { 
    x, y := 0, 1 
    for { 
     select { 
     case c <- x: 
      x, y = y, x + y 
     case <- quit: 
      fmt.Println("quit") 
      return 
     } 
    } 
} 

func main() { 
    c := make(chan int) 
    quit := make(chan int) 
    go func() { 
     for i := 0; i < 10; i++ { 
      fmt.Println(<- c) 
     } 
     quit <- 0 
    }() 
    fibonacci(c, quit) 
} 

あり、私に混乱している。この程度はかなりビットがあり、ツアー自体はそれについて多くを言っていません。 。それは選択が通信操作を待つと言いますが、fibonacciを呼び出す前に、それがゴルーチンに送信する関数にどのように適用されるのか実際にはわかりません。 fmt.Printlnがチャネルcに送信されていますが、理由や理由がわかりません。

私はこれについて多くの質問をしていますが、最初の部分...

答えて

3

コード例では、ゴルーチンが起動され、fmt.Println(<- c)に達するまで実行され、cから受け取った値が出力されます。この時点で、i == 0が最初の反復に入ります。一方、これはゴルーチンで実行されているので、mainは実行を継続してfibonacciと呼び、cquitのチャネルを渡しています。 fibonacci関数は、無限の選択になっています。つまり、returnquitチャネルから受け取ったときのように明示的に呼び出さなければ、決してこれを抜け出せません。だから、バックメインで、あなたがチャンネルから受信するまでゴルーチン、それブロックを呼び出したところ、fibonacciは(ときi == 10)その時実行し、そのチャネル上で送信し、そのループが終了するまでfibonacci順序で次の番号の提供を開始

そこのコードはquit <- 0に移動します。ここでは、終了チャネルで送信されます。 fibonacciに無限の選択があるので、次の利用可能なケースを常に実行します。cで送信を続けることはできません。そのチャネルはバッファされず、1つのアイテムしか許可されず、フルですが、ケースこれはquitチャネルで何かを受け取ったため、quitを出力して返します。

希望に役立ちます。言語の中には100%正確ではないものもあります。実際にこのコントロールフローがどのように機能するかを説明しようとしています。私は実際には、メインのゴルーチンがどの時点で受け取れるかをc <- xステートメントに入れて送信するまで待つことを選択します。すべてが完了した後にチャンネルからアイテムを読み込もうとすると、パニックが発生します。実際には彼らはお互いに待っている、あなたは完全なチャンネルで送信することはできませんし、ちょうど他のコントロールフロー(選択のような)なしでそれを読んだ場合は、受信するまで何かがブロックされます。

+0

最初の部分を助けてくれてありがとうございましたが、select文については混乱しています.Goroutineがチャンネルを「開く」ためにswitch文が読み込まれるため、 'c < - x ' 'xがcに送ることができるかのようなもの;どうすればいい?私が正しいとすれば、どうすれば2番目のケースを解釈できますか? – deltaskelta

+0

@deltaskeltaうん、それは基本的な考えです。それは、それが満たされる最初の条件を実行するスイッチのように考える。あなたは 'quit'チャンネルから受信していますので、' quit'で送信すると 'c'で送信しますので、' c'で読み込んだものが別の書き込みで開かれますその場合に入る。 – evanmcdonnal

関連する問題