3

バッファリングされたチャネルがどのように機能するかを理解するのに苦労しています。次の例に基づいて、一度に 2 つのスレッドを利用して現在の時刻を出力しようとしています。2 つの go 呼び出しごとに約 2 秒の遅延があります。

package main
import "fmt"
import "time"

func main() {
    returnCurrentTime := func() string  {
        return time.Now().String()
    }

    c := make(chan string, 2)

    asyncReturnCurrentTime := func(c chan string) {
        time.Sleep(2001 * time.Millisecond)
        c <- returnCurrentTime()
    }

    for i := 1; i != 7; i++ {
        go asyncReturnCurrentTime(c)
        if(i % 3 == 0) {
            fmt.Println(<- c)
            fmt.Println(<- c)
            fmt.Println(<- c)
            fmt.Println()
        }
    }
}

これにより、

2013-02-27 03:17:50
2013-02-27 03:17:50
2013-02-27 03:17:50

2013-02-27 03:17:52
2013-02-27 03:17:52
2013-02-27 03:17:52

秒に関して私が期待しているのは、2回のgo呼び出しの間に2秒の遅延があり、この場合、次の結果です

2013-02-27 03:17:50
2013-02-27 03:17:50
2013-02-27 03:17:52 <- 3rd call with 2 buffer slots

2013-02-27 03:17:54
2013-02-27 03:17:54
2013-02-27 03:17:56 <- 3rd call with 2 buffer slots

明らかに、バッファリングされたチャネルの概念を誤解していました。誰かが私のロジックの障害と、期待される結果を達成する方法を説明してくれませんか?

ありがとうございました

4

1 に答える 1

3

事実上、あなたは実行しています:

package main

import (
    "fmt"
    "time"
)

func main() {
    returnCurrentTime := func() string {
        return time.Now().String()
    }

    c := make(chan string, 2)

    asyncReturnCurrentTime := func(c chan string) {
        time.Sleep(2001 * time.Millisecond)
        c <- returnCurrentTime()
    }

    go asyncReturnCurrentTime(c)
    go asyncReturnCurrentTime(c)
    go asyncReturnCurrentTime(c)
    fmt.Println(<-c)
    fmt.Println(<-c)
    fmt.Println(<-c)
    fmt.Println()
    go asyncReturnCurrentTime(c)
    go asyncReturnCurrentTime(c)
    go asyncReturnCurrentTime(c)
    fmt.Println(<-c)
    fmt.Println(<-c)
    fmt.Println(<-c)
    fmt.Println()
}

出力:

2013-02-26 21:28:22.069581655 -0500 EST
2013-02-26 21:28:22.069688722 -0500 EST
2013-02-26 21:28:22.069695217 -0500 EST

2013-02-26 21:28:24.070985411 -0500 EST
2013-02-26 21:28:24.070999309 -0500 EST
2013-02-26 21:28:24.071002661 -0500 EST

ステートメントを送信する

通信が開始される前に、チャネルと値式の両方が評価されます。送信が続行できるようになるまで、通信はブロックされます。

returnCurrentTime()式 (タイムスタンプ) は、送信が試行される前にすぐに評価されます。送信のタイムスタンプではありません。バッファがいっぱいの場合、送信は後で発生する可能性があります。

また、実際の送受信時間を測定するとchan c、送信、送信、ブロック、受信、ブロック解除、送信のバッファリング遅延は重要ではなくなります。例えば、

c <-;  2013-02-26 23:29:34.505456624 -0500 EST
c <-;  2013-02-26 23:29:34.505467030 -0500 EST
<- c;  2013-02-26 23:29:34.505468497 -0500 EST
c <-;  2013-02-26 23:29:34.505518015 -0500 EST

c <-;  2013-02-26 23:31:36.506659943 -0500 EST
c <-;  2013-02-26 23:31:36.506664832 -0500 EST
<- c;  2013-02-26 23:31:36.506669302 -0500 EST
c <-;  2013-02-26 23:31:36.506696540 -0500 EST
于 2013-02-27T02:29:54.020 に答える