簡體   English   中英

使用fgets作為非阻塞函數C ++

[英]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更多發送之前正在等待對已發送數據的響應,則可能會掛起。

您基本上有兩個選擇:

  1. 在單獨的線程中運行該循環。
  2. 檢查您的操作系統是否支持用於非阻塞IO的某些API。

這聽起來有點像過大殺傷力,但這是我想到的那個。

使用2個不同的線程-一個使用此循環並等待阻塞(我不認為這可以非阻塞地完成)。 讀取內容后,將其推入管道。

同時,另一個線程將做任何需要做的事情,並不時檢查管道中的數據(顯然,您希望它是異步的,或者至少我是這樣獲得的。如果是這樣,則意味着不同的線程)

但隨后,您將需要很好地同步兩個線程。 您應該檢查操作系統有關多線程和IO操作的信息。

在Linux上,您可以通過按ctrl-d來指定輸入的結尾,當然,您可以使用單獨的線程來完成輸入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM