2017-07-08 29 views
0

はチャンネルを証明する次のプログラムを考えてみましょう:Sleep()と同期の関係はありますか?

package main 

import (
    "fmt" 
) 

func pinger(c chan string) { 
    for i := 0; ; i++ { 
     c <- "ping" 
    } 
} 

func ponger(c chan string) { 
    for i := 0; ; i++ { 
     c <- "pong" 
    } 
} 

func printer(c chan string) { 
    for { 
     msg := <-c 
     fmt.Println(msg) 
     //time.Sleep(time.Second * 1) 
    } 
} 

func main() { 
    var c = make(chan string) 

    go pinger(c) 
    go ponger(c) 
    go printer(c) 

    var input string 
    fmt.Scanln(&input) 
} 

私はtime.Sleep呼び出しのコメントを解除した場合、出力は「ピング」と「ピンポン」の素敵な、予測可能な方法でターンを取っています。ただし、コメントを追加すると、予測できない順序になります。私は初心者で、この同期を可能にしたのかと不思議です。待ち時間を追加すると、残りのチャネルフィーダがそのラインを牽引するのはなぜですか?

答えて

1

Sleep()と同期の関係はありますか?

NO

同期チャネルとチャネルから取得するために送信された値との間に起こります。

var c = make(chan string) 

チャネルcは、一度に1つのタイプの文字列の値を保持できます。値がチャネル<- cから取得されるまで;関数pinger,pongerはチャンネルcに値を送信できません(つまり、pingerとpongerは、プリンタ機能から読み込むまでチャンネルに値を送信するために待機しています)。

この例では、Sleep funcで遅延時間を導入して、プリンタ機能のチャネルcから値を読み取っています。あなたはSleep FUNC :)

+0

の助けを借りていいとスローリードを得る理由です。しかし同じパターンがあるため、読み書きのオーダーで、スリープせずに観察する必要があります

は遅れていること、同じである必要がありますはるかに小さくなります。遅滞なく、出力は "ping ping pong ping ping ping"のようなものです。何故ですか? – dotslash

+0

複数のgoroutineがチャネルオーダーに値を送信する場合、保証されません。チャンネルからの読み値に応じて変化する可能性があります。例えば、あなたのプログラムを実行しました。出力は 'ping ping ping ping ping ping pong pong pong pong pong pong pong'です。典型的には、ルーチンで「スリープ」を使用すると、他のルーチンが再開できるようになる。 'main()' goroutineも同時に実行されます。 – jeevatkm

+0

あなたは私のプログラムを 'Sleep'で実行し、あなたが言及したパターンを持っていたということですか?そうでなければ、これは私の混乱の原因です。 「スリープ」では、「ping」と「pong」が交互に(少なくとも私のマシン上では)睡眠せずに、それらはランダムな順序で出現するようです。 – dotslash

関連する問題