Как предотвратить блокировку fgets, когда в файловом потоке нет новых данных
У меня есть функция popen(), которая выполняет "tail -f sometextfile". В то время как есть данные в filestream, я могу получить данные через fgets(). Теперь, если новые данные не поступают из хвоста, зависает fgets(). Я попробовал ferror() и feof() безрезультатно. Как я могу убедиться, что fgets() не пытается читать данные, когда ничего нового в потоке файлов нет?
Одним из предложений было select(). Поскольку это для Windows Platform, выбор не работает, поскольку анонимные каналы, похоже, не работают для него (см. this post).
Ответы
Ответ 1
В Linux (или любой Unix-y OS) вы можете пометить базовый файловый дескриптор, используемый popen(), чтобы не блокировать.
#include <fcntl.h>
FILE *proc = popen("tail -f /tmp/test.txt", "r");
int fd = fileno(proc);
int flags;
flags = fcntl(fd, F_GETFL, 0);
flags |= O_NONBLOCK;
fcntl(fd, F_SETFL, flags);
Если вход отсутствует, fgets вернет NULL с errno, установленным в EWOULDBLOCK.
Ответ 2
fgets()
- это блокировка чтения, она должна ждать, пока данные не будут доступны, если нет данных.
Вы хотите выполнить асинхронный ввод-вывод с помощью select()
, poll()
или epoll()
. Затем выполните чтение из дескриптора файла, когда имеются данные.
В этих функциях используется файловый дескриптор дескриптора FILE*
, полученный: int fd = fileno(f);
Ответ 3
Я бы использовал функции POSIX для ввода-вывода, а не для библиотеки C, вы могли бы использовать select или poll.
Ответ 4
Вместо этого вы можете попробовать прочитать sometextfile, используя низкоуровневые функции ввода-вывода (open(), read() и т.д.), например, сам хвост. Когда нет ничего более читаемого, read() возвращает ноль, но все равно попытается прочитать больше в следующий раз, в отличие от функций FILE *.
Ответ 5
Я решил свои проблемы, используя потоки, в частности _beginthread
, _beginthreadex
.