文件流没有新数据时如何防止fgets块
时间:2020-03-06 14:53:14 来源:igfitidea点击:
我有一个执行" tail -f sometextfile"的popen()函数。只要文件流中有数据,显然我可以通过fgets()获取数据。现在,如果没有新数据来自尾部,则fgets()将挂起。我尝试了ferror()和feof()无济于事。当文件流中没有新内容时,如何确保fgets()不会尝试读取数据?
建议之一是select()。由于这是针对Windows平台的,因此select似乎不起作用,因为匿名管道似乎不适用于它(请参阅此文章)。
解决方案
如果我们将POSIX函数用于IO而不是C库,则可以使用select或者poll。
相反,我们可以尝试使用低级IO功能(open(),read()等)读取sometextfile,就像tail本身一样。当没有更多要读取的内容时,read()会返回零,但下次仍将尝试读取更多内容,这与FILE *函数不同。
fgets()是一个阻塞读取,如果没有数据,它应该等到数据可用为止。
我们需要使用select(),poll()或者epoll()执行异步I / O。当有可用数据时,然后从文件描述符执行读取。
这些函数使用" FILE *"句柄的文件描述符,可以通过以下方式检索:" int fd = fileno(f);"。
在Linux(或者任何Unix-y OS)中,可以将popen()使用的基础文件描述符标记为非阻塞。
#include <fcntl.h> FILE *proc = popen("tail -f /tmp/test.txt", "r"); int fd = fileno(proc); int flags; flags = fcntl(fd, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(fd, F_SETFL, flags);
如果没有可用的输入,则fgets将errno设置为EWOULDBLOCK时返回NULL。
我通过使用线程(特别是_beginthread和_beginthreadex)解决了我的问题。