прочитайте последнюю строчку fifo - PullRequest
1 голос
/ 21 февраля 2010

Вот ситуация: какой-то процесс записывает строки в файл fifo (созданный с помощью mkfifo). В какой-то момент в моей программе я хочу прочитать последнюю строку в fifo и отбросить все остальные. Процедура может блокироваться, только если в fifo меньше одной строки.

Не могу придумать чистый способ сделать это, есть идеи?

РЕДАКТИРОВАТЬ: Процесс записи никогда не остановит запись строк в fifo. То, что я имею в виду под последней строкой, является последним ко времени, когда я читал fifo. Это не обязательно сопровождается EOF.

Ответы [ 3 ]

2 голосов
/ 21 февраля 2010

Если ваша основная проблема заключается в том, что чтение заблокируется, откройте FIFO как неблокирующее. Я предполагаю, что вы знаете, что вы ищете в потоке, и просто отбросите все раньше.

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

2 голосов
/ 21 февраля 2010

Если я правильно понял вашу проблему, у вас есть другой процесс, который загружает в вашу программу данные, превышающие fifo, и новые данные устаревают из всех ранее полученных данных, поэтому вас интересуют только самые последние доступные данные.

В этом случае мой подход будет следующим: установить неблокирующий режим для дескриптора fifo, используя флаг O_NONBLOCK для fcntl() системного вызова, и использовать что-то вроде этого:

while (!exit_condition) {
    bytes = read(fd, wrkbuf, sizeof(wrkbuf));  // error handling omitted
    if (0 == bytes && bytes_to_process > 0) {
        process(wrkbuf, bytes_to_process);
        bytes_to_process = 0;
    } else
        bytes_to_process = bytes;
}
1 голос
/ 21 февраля 2010

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

Считывание последней строки и отбрасывание всех остальных - это просто процесс отслеживания указателя на последнее сообщение и, при желании, очистки очереди.

Проблемы здесь заключаются в том, что ваша внутренняя очередь может стать большой, и вам потребуется контроль параллелизма для указателей очереди и последнего сообщения. Я хотел бы, чтобы читатель FIFO в своем собственном потоке ничего не делал, кроме как слушал трубку. Когда приходит сообщение, вам нужно заблокировать очередь, добавить новое сообщение и обновить указатель последнего сообщения, а затем снять блокировку. Убедитесь, что вы обрабатываете все доступные входящие сообщения перед снятием блокировки. В потоке, выполняющем обработку, вы должны заблокировать очередь для работы с ней. Убедитесь, что вы блокируете очередь не дольше, чем это необходимо, иначе у вас будут проблемы с производительностью.

...