2010-09-14 66 views

回答

10

您可以使用ncurses,或者如果你不想,你就可以按照本blog post描述的使用選擇。基本上,您可以使用select並指定超時。如果stdin FD被設置,那麼你可以安全地讀取它,並且不會阻塞。如果你想在選擇更多的信息,請檢查this了,當然還有wikipedia。知道這是一個方便的電話。

編輯:我覺得不得不提供代碼,所以在這裏,直接從博客文章發表一些評論。調用read()

// if != 0, then there is data to be read on stdin 
int kbhit() 
{ 
    // timeout structure passed into select 
    struct timeval tv; 
    // fd_set passed into select 
    fd_set fds; 
    // Set up the timeout. here we can wait for 1 second 
    tv.tv_sec = 1; 
    tv.tv_usec = 0; 

    // Zero out the fd_set - make sure it's pristine 
    FD_ZERO(&fds); 
    // Set the FD that we want to read 
    FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 
    // select takes the last file descriptor value + 1 in the fdset to check, 
    // the fdset for reads, writes, and errors. We are only passing in reads. 
    // the last parameter is the timeout. select will return if an FD is ready or 
    // the timeout has occurred 
    select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); 
    // return 0 if STDIN is not ready to be read. 
    return FD_ISSET(STDIN_FILENO, &fds); 
} 
+0

+1好博文。 – Tom 2010-09-14 19:09:59

0

呼叫alarm()ualarm()。這將導致SIGALRM信號被傳送到進程,中斷read(),提供的你沒有告訴O/S在中斷後重新啓動系統調用。如果read()正常返回,請務必取消報警。

+1

'SIGALRM'的默認吊掛器會終止這個過程,所以您需要安裝一個信號處理器。在一個理智的操作系統中,默認情況下,信號不會中斷系統調用,所以您需要使用'sigaction'而不是'signal'來確保它們。 – 2010-09-15 00:29:48

6

使用select,poll或任何其他IO複用工具。他們都採取超時的說法。 請注意,如果stdin是普通文件,這將不起作用,但如果stdin是終端/ tty,套接字,管道,則它將不起作用。

例如

fd_set selectset; 
struct timeval timeout = {10,0}; //timeout of 10 secs. 
int ret; 
FD_ZERO(&selectset); 
FD_SET(0,&selectset); 
ret = select(1,&selectset,NULL,NULL,&timeout); 
if(ret == 0) 
    //timeout 
else if(ret == -1) 
    //error 
else 
    // stdin has data, read it 
    // (we know stdin is readable, since we only asked for read events 
    //and stdin is the only fd in our select set. 
+0

+1對於不依賴於信號並且與進程的全局狀態相混淆的答案,這可能不適合於庫代碼。 – 2010-09-15 00:30:39

+0

嗯,它會「工作」一個普通的文件,因爲它總是會說從它讀取不會阻塞,這是真的(等待磁盤或網絡文件系統提供數據不被視爲「阻塞」) 。 – caf 2010-09-15 01:55:46

+0

沒錯,它不算作阻塞,但它可以阻塞相當長的時間。 – nos 2010-09-15 07:34:23