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

glu*_*utz 10 c file-io select

这是来自"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);
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*ler 16

磁盘文件随时可以读取(但如果您已经在文件末尾,则读取可能返回0个字节),因此您无法select()在磁盘文件上使用以查找何时将新数据添加到文件中.

POSIX说:

与常规文件关联的文件描述符应始终为准备读取,准备写入和错误条件选择为true.

此外,正如cnicutar在现在删除的帖子中指出的那样,通常,您必须在每次迭代时初始化FD_SET.在你的代码中,你正在监视一个fd,并且fd总是准备就绪,所以FD_SET实际上并没有改变.但是,如果要监视5个描述符,并select检测到只有一个准备好,那么在下一次迭代中,只会监视一个描述符(除非重置FD_SET).这使得使用select棘手.

  • AFAIK `poll` 也不能用于监视常规文件的更改。那么唯一的方法是“inotify”?问题是基于“inotify”的解决方案适用于文件路径,而不适用于已打开的文件描述符。 (3认同)