[英]using fgets as non-blocking function c++
我正在編寫一個使用fgets函數從stdin循環讀取的程序,如下所示:
while(fgets(buffer2, BUFFERSIZE , stdin) != NULL){
//Some code
}
我希望我的代碼是非阻塞的,也就是說:當用戶暫時沒有輸入時,我不希望程序保持在“ fgets”行中。
我該怎么做?
fgets()
是一個阻止函數,它的作用是等待數據可用。
如果要執行異步I / O,則可以使用select()
, poll()
或epoll()
。 當有可用數據時,然后從文件描述符執行讀取。
這些函數使用FILE *句柄的文件描述符,該描述符通過以下方式檢索:
int fd = fileno(f);
如果使用的是Unix或Linux,則一種解決方案是將文件使用的文件描述符標記為非阻塞。 例:
#include <fcntl.h>
FILE *handle = popen("tail -f /als/als_test.txt", "r");
int fd = fileno(handle);
flags = fcntl(fd, F_GETFL, 0);
flags |= O_NONBLOCK;
fcntl(fd, F_SETFL, flags);
fgets
現在應該是非阻塞的,並且將返回null並為您設置錯誤代碼。
如果您具有適當的POSIX環境,則可以在調用
... fgets()
read()
之前,使用select()
或poll()
在stdin
的描述符上檢查輸入。
Jan在下面的評論(謝謝!)解釋了為什么您不能通過這種方法使用fgets()
...總之,在FILE
對象中還有一層額外的緩沖,盡管select()
什么也沒找到,但是數據已經可以等待了有關文件描述符的更多信息...防止您的程序及時響應,如果其他系統在對stdin
更多發送之前正在等待對已發送數據的響應,則可能會掛起。
您基本上有兩個選擇:
這聽起來有點像過大殺傷力,但這是我想到的那個。
使用2個不同的線程-一個使用此循環並等待阻塞(我不認為這可以非阻塞地完成)。 讀取內容后,將其推入管道。
同時,另一個線程將做任何需要做的事情,並不時檢查管道中的數據(顯然,您希望它是異步的,或者至少我是這樣獲得的。如果是這樣,則意味着不同的線程)
但隨后,您將需要很好地同步兩個線程。 您應該檢查操作系統有關多線程和IO操作的信息。
在Linux上,您可以通過按ctrl-d來指定輸入的結尾,當然,您可以使用單獨的線程來完成輸入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.