1. linux可以发信号/中断的方法实现。
2. windows/linux 通用方法
bool wait_stdin_line( int ms )
{
#ifdef WIN32
HANDLE eventHandles = GetStdHandle(STD_INPUT_HANDLE) ;
DWORD result = WSAWaitForMultipleEvents( 1,
&eventHandles ,
TRUE,
ms,
TRUE
);
if( result != WSA_WAIT_EVENT_0 ) return false ;
INPUT_RECORD record;
DWORD numRead;
if(!PeekConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &record, 1, &numRead)) {
return false;
}
if( record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown) {
ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &record, 1, &numRead) ;
return false;
}
return true;
#else
tick_t start = sysinfo::get_tick_count();
struct timeval tv;
tv.tv_sec = ms / 1000;
tv.tv_usec = ( ms % 1000 )*1000;
fd_set fds;
FD_ZERO(&fds);
int r = 0 ;
FD_SET(STDIN_FILENO, &fds); // STDIN_FILENO = stdin = 0
my_loop:
r = select( STDIN_FILENO+1, &fds, NULL, NULL, &tv) ;
if( r == 0 ) return false ; // timeout
if( r == -1 && errno == EINTR ){
// or pselect( ..., signal_set ) 代替 select, 就无需这个 loop 了
// 代码会简洁 , 但会导致信号处理线程变少
int lapse = (int)get_tick_lapse( start ) ;
if( lapse >= ms ) return false ;
else{
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
lapse = ms - lapse ;
tv.tv_sec = lapse/ 1000;
tv.tv_usec = ( lapse% 1000 )*1000;
goto my_loop ;
}
}
return true ;
#endif
}