douyan2002 2015-06-30 18:53
浏览 16
已采纳

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

I am trying to make a terminal golang application, where a user has 4 seconds to input something. If he inputted something faster, print result and ask him input again for 4 seconds.

If a user will not return input in 4 seconds, the program must write time out and ask him input again.

My code does this, but only once. After the first timeout it won't return any result even if a user was faster that 4 seconds. I cannot figure out why this is so.

The code

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('
')
    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")
        }
    }
}

The output:

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条回答 默认 最新

  • doupeizheng3918 2015-06-30 19:22
    关注

    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('
    ')
            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")
            }
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题
  • ¥30 python代码,帮调试
  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿