开发者

Add a Timeout for getchar()

开发者 https://www.devze.com 2023-02-17 15:35 出处:网络
I need to add a timeout function for getchar() in my program. What do I do so that when my program reaches the instruction getchar(), it will only wait for a certain amount of time for the user to m

I need to add a timeout function for getchar() in my program.

What do I do so that when my program reaches the instruction getchar(), it will only wait for a certain amount of time for the user to make a keystroke and if the user does no开发者_JAVA百科t make a keystroke within the given time limit, the program will "skip" the getchar()?

The operating system does not support the conio.h library so kbhit is not an option.


This is usually achieved by using select() on stdin. Another solution would be using alarm() and a dummy SIGALRM handler to interrupt the getchar() call (only working on POSIX systems though).


How to add a timeout when reading from `stdin` I found this question is helpful.

Another method is using multithreading.

If you are using c++11, you can make use of condition_variable::wait_for() as a timer thread. And the original getchar() is blocking on another thread.

Here is an example:

#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;
}

When there is a keystroke, main thread will notify the worker thread.

0

精彩评论

暂无评论...
验证码 换一张
取 消