time.NewTimer не работает, как я ожидаю - PullRequest
0 голосов
/ 09 июня 2018

У меня есть довольно простая программа, которая должна автоматически завершаться через определенный промежуток времени (например, одну секунду)

Код:

package main

import (
    "fmt"
    "time"
)

func emit(wordChannel chan string, done chan bool) {
    defer close(wordChannel)

    words := []string{"The", "quick", "brown", "fox"}
    i := 0
    t := time.NewTimer(1 * time.Second)

    for {
        select {
        case wordChannel <- words[i]:
            i++
            if i == len(words) {
                i = 0
            }
        // Please ignore the following case
        case <-done:
            done <- true
            // fmt.Printf("Got done!\n")
            close(done)
            return
        case <-t.C:
            fmt.Printf("\n\nGot done!\n\n")
            return
        }
    }
}

func main() {

    mainWordChannel := make(chan string)
    // Please ignore mainDoneChannel
    mainDoneChannel := make(chan bool)

    go emit(mainWordChannel, mainDoneChannel)

    for word := range mainWordChannel {
        fmt.Printf("%s  ", word)
    }

}

Я компилируюи выполнить двоичный файл, и вы можете увидеть выполнение здесь .

Это явно выше 1 секунды.

Документация Go на NewTimer гласит:

func NewTimer

func NewTimer(d Duration) *Timer

NewTimer создает новый таймер, который будет посылать текущее время на своем канале, по крайней мере, через некоторое время d.

Может ли кто-нибудь помочь мне понять, что здесь происходит?Почему программа не завершается точно (или близко at least) через 1 секунду?

1 Ответ

0 голосов
/ 09 июня 2018

Таймер работает как задумано.Он отправляет значение в канал.Я думаю, что полезно прочитать об операторе выбора Каждая итерация в вашем цикле может записывать в канал.Если> 1 связь может продолжаться, то нет никакой гарантии.Таким образом, если добавить задержку для цикла чтения следующим образом:

for word := range mainWordChannel {
    fmt.Printf("%s  ", word)
    time.Sleep(time.Millisecond)
}

В этом случае может продолжаться только чтение с timer.C.И программа закончится.

...