Как предотвратить блокировку 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.