当文件流没有新数据时如何防止fgets阻塞

时间:2008-09-29 17:51:48

标签: c popen fgets

我有一个执行“tail -f sometextfile”的popen()函数。只要文件流中有数据显然我可以通过fgets()获取数据。现在,如果没有来自尾部的新数据,fgets()会挂起。我试过ferror()和feof()无济于事。如何在文件流中没有新内容的情况下确保fgets()不会尝试读取数据?

其中一个建议是select()。由于这是针对Windows平台选择似乎不起作用,因为匿名管道似乎不起作用(请参阅this post)。

5 个答案:

答案 0 :(得分:26)

在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将返回NULL,并将errno设置为EWOULDBLOCK。

答案 1 :(得分:15)

fgets()是阻塞读取,如果没有数据,它应该等到数据可用。

您需要使用select()poll()epoll()执行异步I / O.然后在有可用数据时从文件描述符执行读取。

这些函数使用FILE*句柄的文件描述符,检索方式为:int fd = fileno(f);

答案 2 :(得分:1)

我通过使用线程解决了我的问题,特别是_beginthread , _beginthreadex

答案 3 :(得分:0)

我会使用POSIX函数代替C库的函数,你可以使用selectpoll

答案 4 :(得分:0)

您可以尝试使用低级IO函数(open(),read()等)读取sometext文件,就像tail本身一样。当没有其他内容可读时,read()返回零,但下次仍会尝试读取更多内容,与FILE *函数不同。