select()不等待

时间:2010-09-04 12:33:47

标签: c file select file-io

我要阅读程序日志文件,为此我想使用select()和read()

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <fcntl.h>
#include <stdio.h>


int main()
{
    int fd = -1;
    fd_set fds;
    struct timeval tv;
    int rc; 
    char buffer[4096];
    char * log_path = "/home/mich/a.txt";
    if((fd = open(log_path,O_RDONLY) ) == -1 )
    {
        printf("error\n");
            return -1;
    }

    while(1)
    {

        FD_ZERO(&fds);
        FD_SET(fd,&fds); 
        tv.tv_sec = 2;
        tv.tv_usec = 0;
        rc = select(fd+1, &fds, NULL, NULL, &tv);

            if (rc < 0) {
                printf("failed\n");
                continue;
            } else if (rc > 0 && FD_ISSET(fd,&fds)) {
                printf("read\n");
            } else  {
                printf("timeout\n");
                continue;
            }
        while ((my_getline(buffer,sizeof(buffer),fd)) > 0)  
        {
            printf("%s",buffer);
        }   
    }
    close(fd);
}

my_getline是一个使用read()。

的函数

输出:

read
aaa
read
read
read
read
read
bbb
read
read
read
read
...

其中aaa和bbb是读取文件中的行。

这个程序有什么问题?

2 个答案:

答案 0 :(得分:4)

select()告诉您read()不会阻止。

这包括返回0以指示文件结束的情况,这可能是你得到的结果。

答案 1 :(得分:2)

select告诉您fd上有等待的内容。这不必是一行,可以是单个字节,也可以是已到达文件末尾的信息。在外部puts("####");循环的末尾添加while,以查看代码如何处理输入文件。

要了解如何继续读取其他进程附加的文件,请查看unix tail实用程序(特别是其-f选项)的一个免费实现的源代码。传统的实现是读取整个文件,睡眠一小段时间(tail中的1秒),并从上次读取后离开的位置重复。更现代,更具反应性,资源消耗更少但便携性更低的方法使用文件更改通知API(Linux下的inotify,* BSD下的kqueue,......)。