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 certai
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.
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).