终端应用程序中的输入超时

时间:2015-06-30 18:53:55

标签: go

我正在尝试创建一个终端golang应用程序,用户有4秒钟输入内容。如果他输入更快的东西,打印结果并再次要求他输入4秒钟。

如果用户在4秒内没有返回输入,程序必须写time out并再次询问他输入。

我的代码执行此操作,但只执行一次。在第一个timeout之后,即使用户速度超过4秒,它也不会返回任何结果。我无法弄清楚为什么会这样。

代码

package main

import (
    "bufio"
    "fmt"
    "log"
    "os"
    "time"
)

var (
    result string
    err    error
)

func getInput(input chan string) {
    in := bufio.NewReader(os.Stdin)
    result, err := in.ReadString('\n')
    if err != nil {
        log.Fatal(err)
    }

    input <- result
}

func main() {
    for {
        fmt.Println("input something")
        input := make(chan string, 1)
        go getInput(input)

        select {
        case i := <-input:
            fmt.Println("result")
            fmt.Println(i)
        case <-time.After(4000 * time.Millisecond):
            fmt.Println("timed out")
        }
    }
}

输出:

input something
123
result
123

input something
2
result
2

input something
timed out
input something
2
timed out
input something
timed out
input something

1 个答案:

答案 0 :(得分:3)

The problem has to do with the way you're getting the user's input. On a timeout you spawn a new go routine asking for input, but the old one that you had spawned previously is still there grabbing input and sending it to a channel that no one is listening to any more.

Changing it to something like this would fix the problem:

func getInput(input chan string) {
    for {
        in := bufio.NewReader(os.Stdin)
        result, err := in.ReadString('\n')
        if err != nil {
            log.Fatal(err)
        }

        input <- result
    }
}

func main() {
    input := make(chan string, 1)
    go getInput(input)

    for {
        fmt.Println("input something")

        select {
        case i := <-input:
            fmt.Println("result")
            fmt.Println(i)
        case <-time.After(4000 * time.Millisecond):
            fmt.Println("timed out")
        }
    }
}