7

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

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

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

4

2 回答 2

6

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

于 2011-03-16T07:30:26.430 回答
1

How to add 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;
}

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

于 2019-08-15T17:11:35.480 回答