2013-04-22 3 views
0

Существует много файлов, созданных в сетевой файловой системе (NFS). Существует аналогичный вопрос без правильного решения: inotify with NFS.Как сделать мультиплексирование ввода/вывода для чтения нескольких файлов при увеличении размера файла?

Я использую 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"); 
} 

Результат будет следующим: if 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). –

0

В Unix обычные файлы всегда считаются «быстрыми устройствами», поэтому они не могут быть опрошены. То есть, как вы выяснили, они всегда возвращаются «готовы», если вы попытаетесь выбрать() или poll() на них. IIRC - конкретный Linux-релиз возвращает ошибку, если вы попытаетесь опросить обычный fd.

Если вы хотите интегрировать что-то подобное в свой цикл событий, вам нужно будет применить клейкую ленту. Например. имеют отдельный поток, который через подходящие интервалы пытается прочитать()/fstat()/stat() файл/fd, а затем, если он обнаружит, что новые данные доступны, отправьте сообщение в трубу. В главном цикле событий вы можете опросить трубку.

+0

Спасибо за ваш комментарий, вот что я сделал. Но мне интересно, есть ли другой метод без какой-либо задержки в моем коде и освободить загрузку процессора. –