select()如何等待常规文件描述符(非套接字)? [英] How can select() wait on regular file descriptors (non-sockets)?

查看:133
本文介绍了select()如何等待常规文件描述符(非套接字)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是man select的代码示例,加上几行来读取正在写入的实际文件。我怀疑当 ./ myfile.txt 被写入时,选择会返回,现在可以读取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);

/ *观看标准输入(fd 0)以查看输入的时间。 * /
FD_ZERO(& rfds);
FD_SET(0,& rfds);
FD_SET(fd_file,& rfds);

/ *等待五秒钟。 * /
tv.tv_sec = 5;
tv.tv_usec = 0;

while(1)
{
retval = select(fd_file + 1,& rfds,NULL,NULL,& tv);
/ *现在不要依赖电视的价值! * /

if(retval == -1)
perror(select());
else if(retval)
printf(Data is available now.\\\
);
/ * FD_ISSET(0,& rfds)将为真。 * /
else
printf(五秒内没有数据。);
}

exit(EXIT_SUCCESS);

$ / code $ / $ p

解决方案

磁盘文件随时可用读取(但是如果您已经在文件末尾,读取可能会返回0个字节),所以您不能使用 select() ,以确定何时将新数据添加到文件中。



POSIX说:
$ b


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

另外,正如 cnicutar 在一个现在被删除的文章中指出,一般来说,你必须在每次迭代时初始化FD_SET。在你的代码中,你正在监视一个fd,并且这个fd总是准备好,所以FD_SET实际上并没有改变。但是,如果有5个描述符要监视,并且选择检测到只有一个准备就绪,那么在下一次迭代中,只有一个描述符将被监视(除非您重置FD_SET)。这使得使用 select tricky。


This is the code sample from "man select" plus a few lines to read an actual file which is being written to. I suspected that when the ./myfile.txt is written to, select would return that it can now read from that fd. But what happens is that select constantly returns in the while loop so long as the txt file exists. I want it to only return when new data is written to the end of the file. I thought that is how it should work.

#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);
}

解决方案

Disk files are always ready to read (but the read might return 0 bytes if you're already at the end of the file), so you can't use select() on a disk file to find out when new data is added to the file.

POSIX says:

File descriptors associated with regular files shall always select true for ready to read, ready to write, and error conditions.

Also, as cnicutar pointed out in a now-deleted post, in general, you have to initialize the FD_SET on each iteration. In your code, you are monitoring one fd, and that fd is always ready, so the FD_SET is not in fact changing. However, if you have 5 decriptors to monitor, and select detects that only one is ready, then on the next iteration, only that one descriptor would be monitored (unless you reset the FD_SET). This makes using select tricky.

这篇关于select()如何等待常规文件描述符(非套接字)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆