2016-03-31 19 views
1

これはgo tutorial select statementと似ていますが、その投稿からの回答は得られませんでした。だから私はここで尋ねた。回答ありがとうございます。golang select文がランダムにケースを選択しない理由

http://tour.golang.org/concurrency/5では、「case c <-x:」は常に準備ができているようです。つまり、このケースではselect文がブロックされません。

文に基づいて、あるケースが実行できるようになるまでブロックを選択すると、そのケースが実行されます。複数のものが用意できれば、無作為に1つを選択します。 "、" case < -quit: select文は "case c < - x:"と "case < -quit:"からランダムに選択する必要があります。しかし、プログラムは常に "case < -quit:"ケースに入ります。

また、selectブロックを以下のように変更しました。最初の10回のループでは、プログラムはランダムに1-6を出力しますが、プログラムは1回終了します(11回目の出力)終了チャネルの値は0です。

私の質問は、なぜ11番目の選択がいつも終了しているのはなぜですか。 case文で

select { 
    case c <- 1: 
     x, y = y, x+y 
    case c <- 2: 
     x, y = y, x+y 
    case c <- 3: 
     x, y = y, x+y 
    case c <- 4: 
     x, y = y, x+y 
    case c <- 5: 
     x, y = y, x+y 
    case c <- 6: 
     x, y = y, x+y 
    case <-quit: 
     fmt.Println("quit") 
     return 
    } 
+0

しかし、 'C < - X 'は、いつ'の例では*ありません*準備ができていますquit'は(リンク先の例に基づいて)です。あなたはツアーの同じコードを使用していますか? – JimB

+0

@JimB私はCチャンネルがバッファされていないことを理解しています。ありがとう! – shiningdo

答えて

3

、あなたは何かがfoo := <- cとしてCをオフに読み取るまでどのブロック(例えばc <- 1cに値を送っています。何かがquitに書き込むと、<-quitがあり、選択から戻ってくるケースに当たるでしょう。この例から

package main 

import (
    "fmt" 
    "time" 
) 

func main() { 
    c := make(chan int) 
    quit := make(chan struct{}) 

    go func(q chan<- struct{}) { 
     time.Sleep(5 * time.Second) 
     q <- struct{}{} 
    }(quit) 

    go func(ch chan<- int) { 
     var x int 
     for range time.Tick(1 * time.Second) { 
      c <- x 
      x++ 
     } 
    }(c) 

    for { 
     select { 
     case foo := <-c: 
      fmt.Println("Foo", foo) 
     case bar := <-c: 
      fmt.Println("Bar", bar) 
     case <-quit: 
      fmt.Println("quit") 
      return 
     } 
    } 
} 

あなたはとしてランダムにあなたのマシン上でプリントアウトした値を見ることができます:

$ go run foo.go 
Bar 0 
Bar 1 
Foo 2 
Bar 3 
quit 

$ go run foo.go 
Bar 0 
Foo 1 
Bar 2 
Bar 3 
quit 
+0

ありがとうございます。あなたの最初の文が理由であるべきです。しかし、この例は理由がないようです。範囲time.Tick(1 *時間のために '(C)'と - {X X ++ } { C <ため のvar X int型 } - 私は '(int型CHちゃん<)FUNCに行くにコードを変更しました。二番目){ select {'あなたはc < - xがブロックされていないことがわかります。元のコードでは、q <-0を別の関数 'func(q chan < - int){ time.Sleep(2 * time.Second) q < - 0 }(quit)'に移動して試してみます< - cを印刷する場合は、デッドロックエラーが発生します。だから多分select文の中のc <-xのみのブロック – shiningdo

+0

私はあなたが言っていることをよく理解していません。 'c < - x'は、cがバッファされていないチャンネルなので、何かが' c'から読んでいない限り、selectではなくどこでもブロックします。http://play.golang.org/p/3BemJwJjTk –

+0

プレイグラウンド自体が確定的なので、あなたはこれを試しています。 –

関連する問題