select()如何等待常规文件描述符(非套接字)?

select()如何等待常规文件描述符(非套接字)?,c,select,file-io,C,Select,File Io,这是man select中的代码示例,外加几行代码,用于读取正在写入的实际文件。我怀疑当写入./myfile.txt时,select会返回现在可以从该fd读取的结果。但是,只要txt文件存在,select就会在while循环中不断返回。我希望它只在新数据写入文件末尾时返回。我想这就是它应该如何工作的 #include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <sys/time.h

这是man select中的代码示例,外加几行代码,用于读取正在写入的实际文件。我怀疑当写入./myfile.txt时,select会返回现在可以从该fd读取的结果。但是,只要txt文件存在,select就会在while循环中不断返回。我希望它只在新数据写入文件末尾时返回。我想这就是它应该如何工作的

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int
main(void)
{
    fd_set rfds;
    struct timeval tv;
    int retval;

    int fd_file = open("/home/myfile.txt", O_RDONLY);

   /* Watch stdin (fd 0) to see when it has input. */
    FD_ZERO(&rfds);
    FD_SET(0, &rfds);
    FD_SET(fd_file, &rfds);

   /* Wait up to five seconds. */
    tv.tv_sec = 5;
    tv.tv_usec = 0;

   while (1)
   {
     retval = select(fd_file+1, &rfds, NULL, NULL, &tv);
     /* Don't rely on the value of tv now! */

     if (retval == -1)
        perror("select()");
     else if (retval)
        printf("Data is available now.\n");
        /* FD_ISSET(0, &rfds) will be true. */
     else
        printf("No data within five seconds.\n");
   }

   exit(EXIT_SUCCESS);
}

磁盘文件始终可以读取,但如果您已经在文件末尾,则读取可能返回0字节,因此您无法在磁盘文件上使用来确定何时将新数据添加到文件中

POSIX说:

与常规文件相关联的文件描述符应始终为“准备读取”、“准备写入”和“错误”条件选择“真”


此外,正如在一篇现已删除的帖子中指出的,一般来说,您必须在每次迭代中初始化FD_集。在您的代码中,您正在监视一个fd,并且该fd始终处于就绪状态,因此fd_集实际上没有改变。但是,如果您有5个描述符要监控,并且select检测到只有一个描述符准备就绪,那么在下一次迭代中,除非您重置FD_集合,否则将只监控一个描述符。这使得使用select变得棘手。

那么您的问题是什么?谁说select只能在套接字上工作?问题已编辑。抱歉造成混淆。select可用于任何文件类型描述符,无论是套接字、文件、管道还是任何类似的描述符。但是,您不能使用它来监视文件写入的时间,因为您必须使用特定于操作系统的内容,例如在Linux上可以使用。我理解您评论的第一部分。但是,我认为在套接字上选择的目的基本上只是监听数据何时写入套接字。一个文件有什么不同?AFAIK轮询也不能用于查看常规文件的更改。所以唯一的办法就是inotify?问题是基于inotify的解决方案使用的是filepath,而不是已经打开的文件描述符。