【问题标题】:Add a Timeout for getchar()为 getchar() 添加超时
【发布时间】:2011-07-16 09:08:57
【问题描述】:

我需要在我的程序中为 getchar() 添加一个超时函数。

我该怎么做,当我的程序到达指令 getchar() 时,它只会等待一定的时间让用户进行击键,如果用户在给定的时间限制内没有击键,程序会“跳过”getchar()?

操作系统不支持 conio.h 库,因此 kbhit 不是一个选项。

【问题讨论】:

    标签: c time input timeout getchar


    【解决方案1】:

    这通常通过在stdin 上使用select() 来实现。另一种解决方案是使用alarm() 和一个虚拟的 SIGALRM 处理程序来中断getchar() 调用(但仅适用于 POSIX 系统)。

    【讨论】:

    • 我认为 alarm() 应该可以解决问题。问题是......我不知道如何使用警报()!您能否发布一些将 alarm() 与 getchar() 一起使用的示例?我无法从 Google 获得任何信息。
    • 您只需在拨打getchar() 之前拨打alarm(duration);。另外,使用signal(SIGALRM, your_handler_func); 安装一个虚拟 sighandler,这样警报信号就不会杀死您的程序。
    【解决方案2】:

    How to add a timeout when reading from `stdin` 我发现这个问题很有帮助。

    另一种方法是使用多线程。

    如果你使用的是c++11,你可以使用condition_variable::wait_for()作为定时器线程。而原来的 getchar() 被另一个线程阻塞了。

    这是一个例子:

    #include <termios.h>
    #include <unistd.h>
    #include <thread>
    #include <chrono>
    #include <iostream>
    
    std::mutex mtx;
    std::condition_variable cv;
    
    int ch;
    bool INPUT_SIGNAL = false;
    
    void getch ( void ) {
      struct termios oldt, newt;
    
      tcgetattr ( STDIN_FILENO, &oldt );
      newt = oldt;
      newt.c_lflag &= ~( ICANON | ECHO );
    
      tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
      ch = getchar();
      tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );
    
      INPUT_SIGNAL = true;  
    
      cv.notify_one();
    }
    
    void timer ( int period ) {
        for(;;) {
            std::unique_lock<std::mutex> lck(mtx);
    
            cv.wait_for(lck, std::chrono::seconds(period), []{return INPUT_SIGNAL;});   
    
            if(INPUT_SIGNAL) {
                INPUT_SIGNAL = false;
                std::cout << ch << "\n";
            } else {
                std::cout << 0 << "\n";
            }
        }
    }
    
    int main() {
        std::thread worker(timer, 1);
        for(;;) {
            getch();
        }
        worker.join();
        return 0;
    }
    

    当有击键时,主线程会通知工作线程。

    【讨论】:

      猜你喜欢
      • 2015-10-22
      • 1970-01-01
      • 1970-01-01
      • 2012-03-04
      • 2012-02-22
      • 2013-01-14
      • 1970-01-01
      • 2011-11-30
      • 2014-10-16
      相关资源
      最近更新 更多