как предотвратить блокировку fgets, когда в файловом потоке нет новых данных - PullRequest
11 голосов
/ 29 сентября 2008

У меня есть функция popen (), которая выполняет "tail -f sometextfile". Пока есть данные в файловом потоке, очевидно, что я могу получить данные через fgets (). Теперь, если из хвоста нет новых данных, fgets () зависает. Я пробовал ferror () и feof () безрезультатно. Как я могу убедиться, что fgets () не пытается читать данные, когда в потоке файлов нет ничего нового?

Одно из предложений было выбрано (). Поскольку это для платформы Windows, выбор, кажется, не работает, поскольку анонимные каналы, кажется, не работают для этого (см. этот пост ).

Ответы [ 5 ]

26 голосов
/ 29 сентября 2008

В Linux (или любой ОС Unix-y) вы можете пометить основной файловый дескриптор, используемый 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.

15 голосов
/ 29 сентября 2008

fgets() - это чтение с блокировкой, предполагается, что данные будут доступны, если данных нет.

Вы хотите выполнить асинхронный ввод / вывод, используя select(), poll() или epoll(). А затем выполните чтение из дескриптора файла, когда есть доступные данные.

В этих функциях используется дескриптор файла дескриптора FILE*, получаемый с помощью: int fd = fileno(f);

1 голос
/ 01 октября 2008

Я решил свои проблемы с помощью потоков, в частности _beginthread, _beginthreadex.

0 голосов
/ 29 сентября 2008

Вместо этого вы можете попробовать прочитать некоторый текстовый файл, используя низкоуровневые функции ввода-вывода (open (), read () и т. Д.), Как это делает сам tail. Когда больше нечего читать, read () возвращает ноль, но все равно попытается прочитать больше в следующий раз, в отличие от функций FILE *.

0 голосов
/ 29 сентября 2008

Если бы вы использовали функции POSIX для ввода-вывода вместо функций библиотеки C, вы можете использовать select или poll .

...