Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 当文件流没有新数据时,如何防止fgets阻塞_C_Popen_Fgets - Fatal编程技术网

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

C 当文件流没有新数据时,如何防止fgets阻塞,c,popen,fgets,C,Popen,Fgets,我有一个popen函数,它执行tail-f sometextfile。显然,只要文件流中有数据,我就可以通过fgets获取数据。现在,如果没有来自tail的新数据,fgets将挂起。我试过费罗和费奥夫,但都没用。当文件流中没有新内容时,如何确保fgets不会尝试读取数据 建议之一是选择。由于这是针对Windows平台的,所以select似乎不起作用,因为匿名管道似乎不适用于它。请参见。如果您将POSIX函数用于IO而不是C库,则可以使用或。您可以改为使用低级IO函数打开、读取等来读取文本文件,就

我有一个popen函数,它执行tail-f sometextfile。显然,只要文件流中有数据,我就可以通过fgets获取数据。现在,如果没有来自tail的新数据,fgets将挂起。我试过费罗和费奥夫,但都没用。当文件流中没有新内容时,如何确保fgets不会尝试读取数据


建议之一是选择。由于这是针对Windows平台的,所以select似乎不起作用,因为匿名管道似乎不适用于它。请参见。

如果您将POSIX函数用于IO而不是C库,则可以使用或。

您可以改为使用低级IO函数打开、读取等来读取文本文件,就像tail本身一样。当没有更多的数据可读取时,read返回零,但下次仍将尝试读取更多数据,这与FILE*函数不同。

fgets是一种阻塞读取,如果没有数据,则应等待数据可用

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


这些函数使用文件*句柄的文件描述符,通过以下方式检索:int fd=filenof

在Linux或任何Unix-y操作系统中,您可以将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设置为eWoldBlock。

我通过使用线程解决了我的问题。

这只是一个示例。其思想是提取数据并通过互斥对象将其传递给flash实例。如果您有一个文件描述符,并且需要一个文件*,请使用fdopen。不幸的是,我认为select在Windows下的管道上不起作用。混合使用select和FGET是危险的。文件*包含select不知道的内部缓冲区。正确答案是O_NONBLOCK。如果您回答了自己的问题,请将此设置为答案,并可能发布您的解决方案。