2013-04-22 11 views
0

在网络共享文件系统(NFS)上生成了许多文件。 还有一个类似的问题没有适当的解决方案:inotify with NFS如何在文件大小增加时多路复用读取多个文件的I/O?

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

但是,我甚至发现文件直到文件结束,它仍然返回准备好读状态。

你能否提出更好的方法来编写这段代码?

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 

回答

0

当文件发生变化时,NFS没有办法通知客户端,所以你很不幸运。你需要进行民意调查。

+0

你是说如果我使用epoll/poll,它可以解决这个问题吗? (共享文件位于NFS上,我无法触及NFS服务器框)。 – 2013-04-22 07:19:28

0

在Unix中,常规文件总是被认为是“快速设备”,所以它们不能被轮询。也就是说,正如您发现的那样,如果您尝试对它们选择()或poll(),它们总是返回“ready”。 IIRC Linux特定的epoll会直接返回错误,如果您尝试在常规fd上进行轮询。

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

+0

感谢您的评论,这就是我所做的。但我不知道是否有其他方法没有任何延迟我的代码并释放CPU负载也。 – 2013-04-23 03:35:15