2

私はゴルーチン/チャネルを使用しています。これが私のコードです。タイムアウトのケースが実行されないのはなぜですか?

func main() {
    c1 := make(chan int, 1)

    go func() {
        for {
            time.Sleep(1500 * time.Millisecond)
            c1 <- 10
        }
    }()

    go func() {
        for {
            select {
            case i := <-c1:
                fmt.Println(i)
            case <-time.After(2000 * time.Millisecond):
                fmt.Println("TIMEOUT") // <-- Not Executed
            }
        }
    }()

    fmt.Scanln()
}
4

1 に答える 1

3

タイムアウトは発生しません。これは、ゴルーチンの 1 つが 1.5 秒ごと (またはその程度) にチャネルに値を繰り返し送信し、2 秒間c1受信する値がない場合にのみタイムアウトが発生するためです。c1

から値が受信されると、再度c1実行される次の反復で新しい呼び出しが行われ、新しいチャネルが返され、さらに 2 秒後にのみ値が送信されます。前回の実行からのタイムアウト チャネルは破棄され、使用されなくなります。select time.After()select

2 秒後にタイムアウトを受け取るには、タイムアウト チャネルを 1 回だけ作成します。

timeout := time.After(2000 * time.Millisecond)
for {
    select {
    case i := <-c1:
        fmt.Println(i)
    case <-timeout:
        fmt.Println("TIMEOUT") // Will get executed after 2 sec
    }
}

出力:

10
TIMEOUT
10
10
10
...
于 2016-01-20T08:35:29.080 に答える