使用fgets作为非阻塞函数c ++

时间:2011-05-19 08:16:29

标签: c++ nonblocking fgets

我正在编写一个程序,使用函数fgets从stdin读取循环,如下所示:

while(fgets(buffer2, BUFFERSIZE , stdin) != NULL){
  //Some code  
}

我希望我的代码是非阻塞的,即:当用户暂时没有输入时,我不希望程序保留在'fgets'行。
我该怎么办?

5 个答案:

答案 0 :(得分:3)

fgets() 是阻止功能,它应该等到数据可用。

如果您要执行异步I / O,可以使用 select() poll() {{1} } 即可。然后在有可用数据时从文件描述符执行读取。

这些函数使用FILE *句柄的文件描述符,检索方式为:

epoll()

如果您使用的是Unix或Linux,那么一种解决方案可以是将文件使用的文件描述符标记为非阻塞。示例:

int fd = fileno(f);

#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); 现在应该是非阻止的,并且将返回null并为您设置错误代码。

答案 1 :(得分:2)

如果你有一个合适的POSIX环境,你可以使用select()poll()检查stdin描述符上的输入,然后再调用 fgets() ...... read()

Jan的评论如下(谢谢!)解释了为什么你不能使用fgets()这种方法......总之,FILE对象中有一层额外的缓冲,数据已经可以了等待虽然select()在文件描述符上找不到任何其他内容...阻止您的程序及时响应,如果其他系统在发送更多内容之前等待对已发送数据的响应,可能会挂起{1}}。

答案 2 :(得分:1)

您基本上有两个选择:

  1. 在一个单独的线程中运行该循环。
  2. 检查您的操作系统是否支持某些非阻塞IO的API。

答案 3 :(得分:0)

这听起来有点像矫枉过正,但这就是我想到的那个。

使用2个不同的线程 - 一个使用此循环并等待阻塞(我不认为这可以完成非阻塞)。当读取某些内容时,将其推入管道。

与此同时,另一个线程会做任何需要做的事情并不时检查管道中的数据(显然,你希望这是异步的,或者至少我这样做。如果是这样,这意味着不同的主题)

但是,你需要很好地同步这两个线程。您应该检查有关多线程和IO操作的操作系统。

答案 4 :(得分:0)

在Linux上,您可以通过按 ctrl-d 指定输入结束,当然您可以使用单独的线程执行此操作。