2017-03-09 26 views
0

私はテストコードを書いたが、なぜこの結果が得られるのか分からない。golang:コルーチンとチャンネルに奇妙な問題があります

マイsub()更新または私は10のゴールーチンcon()を開始したチャネル値

send 1 = counter++ 
send 0 = return counter 

に基づいてcounterを、返す必要があります。 チャネルに多くの1を送信するだけです(この増加カウンタ)
1秒待ってから0をチャネルに送信します。どのような価値がありますか?私が最初に考えて

が、私は "ランダム" 値、 を取得するが、私は100000を取得する今、私は変更

(OK 10倍の10000は、1秒よりも高速です)

for i:=0; i < 10; i++ { 

for i:=0; i < 10000; i++ { 

今戻った値は1です

なぜ!?

fmt.Println(counter)のコメントを外してmain()にします。 あなたはカウンターの作品を見ると、2つのチャンネル、この作品で、この「ランダム」数

package main 

import (
    "fmt" 
    "time" 
) 

var ch chan int = make(chan int) 
var counter int 

func main() { 
    go sub() 

    for i:=0; i < 10; i++ { //change to 10000 
     go con() 
    } 

    time.Sleep(1000 * time.Millisecond) 

    ch <- 0 
    fmt.Println(<- ch) 
    //fmt.Println(counter) //uncomment this 
} 

func sub() { 
    for c := range ch { 
     if c == 0 { ch <- counter } 
     if c == 1 { counter++ } 
    } 
} 

func con() { 
    for i := 0; i < 10000; i++ { 
     ch <- 1 
    } 
} 
+0

'main'または' sub'が最初に引っ張ってくるならば、あなたが言うことができないためです'ch'から。コマンドとデータを送信するには、異なるチャネルを使用します。 2チャンネルの – zerkms

+0

、これは機能します! しかし、ロジックはどこですか? chはcon()と10xパラレルで使用され、 の場合はsub()で1x、receiveの場合はsubで1xだけ使用されます。 私はこれを理解していません。 – john49384

+0

ああ...ゆっくりと私はそれを理解しています...ありがとうございますzerkms – john49384

答えて

0

を持っていたよう:

package main 

import (
    "fmt" 
    "time" 
) 

var ch chan int = make(chan int) 
var ch2 chan int = make(chan int) 
var counter int 

func main() { 
    go sub() 

    for i:=0; i < 10000; i++ { //change to 10000 
     go con() 
    } 

    time.Sleep(1000 * time.Millisecond) 

    ch2 <- 0 
    fmt.Println(<- ch2) 
    //fmt.Println(counter) //uncomment this 
} 

func sub() { 
    for ;; { 
     select { 
     case <- ch: 
      counter++ 
     case <- ch2: 
      ch2 <- counter 
     } 
    } 
} 

func con() { 
    for i := 0; i < 10000; i++ { 
     ch <- 1 
    } 
}