2013-04-22 12 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