Как выбрать () ждать на обычных дескрипторах файлов (не-сокеты)?

Это образец кода из «man select» плюс несколько строк, чтобы прочитать фактический файл, на который записывается. Я подозревал, что когда ./myfile.txt , select вернет, что теперь он может читать из этого fd. Но происходит то, что select постоянно возвращается в цикле while, пока существует файл txt. Я хочу, чтобы он возвращался только тогда, когда новые данные записывались в конец файла. Я думал, что так оно и должно получиться.

 #include  #include  #include  #include  #include  #include  int main(void) { fd_set rfds; struct timeval tv; int retval; int fd_file = open("/home/myfile.txt", O_RDONLY); /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(0, &rfds); FD_SET(fd_file, &rfds); /* Wait up to five seconds. */ tv.tv_sec = 5; tv.tv_usec = 0; while (1) { retval = select(fd_file+1, &rfds, NULL, NULL, &tv); /* Don't rely on the value of tv now! */ if (retval == -1) perror("select()"); else if (retval) printf("Data is available now.\n"); /* FD_ISSET(0, &rfds) will be true. */ else printf("No data within five seconds.\n"); } exit(EXIT_SUCCESS); } 

Файлы диска всегда готовы к чтению (но чтение может вернуть 0 байтов, если вы уже в конце файла), поэтому вы не можете использовать select() в файле диска, чтобы узнать, когда новые данные добавляются в файл.

POSIX говорит:

Файловые дескрипторы, связанные с регулярными файлами, всегда должны выбирать значение true для готовности к чтению, готовности к записи и условий ошибки.

Кроме того, поскольку cnicutar указывал на удаленную запись, в общем, вам нужно инициализировать FD_SET на каждой итерации. В вашем коде вы отслеживаете один fd, и fd всегда готов, поэтому FD_SET на самом деле не меняется. Тем не менее, если у вас есть 5 декриторов для мониторинга и select обнаружение, что только один готов, то на следующей итерации будет проверяться только один дескриптор (если вы не сбросите FD_SET). Это делает использование сложным.