当文件大小增加时,如何进行复用I/O来读取多个文件?

问题描述 投票:0回答:2

网络共享文件系统(NFS)上生成了许多文件。 有一个类似的问题没有正确的解决方案:inotify with NFS

我使用 select() 来测试文件是否有新数据可以读取。 (其实有些是来自socket描述符,这里只是简化了)。

但是,我发现即使文件直到文件末尾,它仍然返回准备读取状态。

你能建议更好的方法来编写这段代码吗?

fd_set rfds;
struct timeval tv;
int retval;
int i,n,f1,f2,maxfd;
char buf[512];

f1 = fileno(fopen("f1", "rb"));
f2 = fileno(fopen("f2", "rb"));
maxfd = (f1 > f2) ? f1 : f2;

for (i=0; i<3; i++) {
    FD_ZERO(&rfds);
    FD_SET(f1, &rfds);
    FD_SET(f2, &rfds);

    tv.tv_sec = 5;
    tv.tv_usec = 0;

    retval = select(maxfd+1, &rfds, NULL, NULL, &tv);

    if (retval == -1)
        perror("select()");
    else if (retval) {
        printf("Data is available now.\n");
        if (FD_ISSET(f1, &rfds)) {
            n = read(f1, buf, sizeof(buf));
            printf("f1 is ready:%d read %d bytes\n", i, n);
        }
        if (FD_ISSET(f2, &rfds)) {
            n = read(f2, buf, sizeof(buf));
            printf("f2 is ready:%d read %d bytes\n", i, n);
        }
    } else
    printf("No data within five seconds.\n");
}

如果我的 f1 和 f2 包含 3 个字节,输出将如下所示。

Data is available now.
f1 is ready:0 read 3 bytes
f2 is ready:0 read 3 bytes
Data is available now.
f1 is ready:1 read 0 bytes   <- I wish won't enter here
f2 is ready:1 read 0 bytes   <- I wish won't enter here
Data is available now.
f1 is ready:2 read 0 bytes   <- I wish won't enter here
f2 is ready:2 read 0 bytes   <- I wish won't enter here
c file-descriptor posix-select multiplexing
2个回答
0
投票

NFS 无法在文件更改时通知客户端,因此不幸的是您不走运。您需要进行投票。


0
投票

在 Unix 中,常规文件始终被视为“快速设备”,因此无法对其进行轮询。也就是说,正如您所发现的,如果您尝试对它们进行 select() 或 poll() ,它们总是返回“就绪”。 IIRC 如果您尝试轮询常规 fd,则 Linux 特定的 epoll 会直接返回错误。

如果你想将这样的东西集成到你的事件循环中,你必须使用一些胶带。例如。有一个单独的线程,它以适当的时间间隔尝试 read()/fstat()/stat() 文件/fd,然后如果它检测到新数据可用,则向管道发送一条消息。在主事件循环中,您可以轮询管道。

© www.soinside.com 2019 - 2024. All rights reserved.