Стратегия сброса выходных файлов при завершении - PullRequest
2 голосов
/ 22 января 2009

У меня есть приложение, которое отслеживает канал высокоскоростной связи и записывает журналы в файл (через стандартный ввод-вывод файла C). Время отклика на сообщения, поступающие по ссылке, важно, поэтому я сознательно не fflush файл в каждом сообщении, потому что это замедляет мое время отклика.

Однако в некоторых обстоятельствах мое приложение закрывается «насильственно» (например, путем уничтожения процесса), и в этих случаях последние несколько сообщений журнала не записываются (даже если канал связи некоторое время был тихим).

Какие методы / стратегии я могу использовать, чтобы убедиться, что большая часть моих данных сброшена, но без потери скорости ответа?

Редактировать: приложение работает на Windows

Ответы [ 4 ]

4 голосов
/ 22 января 2009

Использование потока является стандартным решением для этого. Пусть ваш код сбора данных записывает данные в потокобезопасную очередь и использует семафор, чтобы сигнализировать о потоке записи.

Однако, прежде чем идти туда, дважды проверьте ваше утверждение, что fflush () будет медленным. Большинство операционных систем имеют кеш файловой системы. Это делает запись очень быстро, как простое копирование из памяти в память. Данные записываются на диск лениво, ваш сбой не повлияет на это.

3 голосов
/ 22 января 2009

Если вы работаете в Unix или Linux, ваш процесс получит некоторый сигнал завершения , который вы можете перехватить (кроме SIGKILL) и fflush() в обработчике сигналов.

Информацию о перехвате сигнала см. man sigaction.

РЕДАКТИРОВАТЬ: понятия не имею о Windows.

1 голос
/ 23 января 2009

Я бы предложил асинхронную запись. Таким образом, вам не нужно ждать, пока произойдет запись IOP, и ОС не будет задерживать IOP. Смотрите флаги CreateFile () FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED.

Вам не нужно FILE_FLAG_NO_BUFFERING. Это только для пропуска кеша ОС. Он понадобится вам только в том случае, если вы беспокоитесь о том, что вся ОС будет умирать.

0 голосов
/ 22 января 2009

Если ваша программа завершается вызовом exit () или возвращением из main (), стандарт C гарантирует, что открытые потоки сбрасываются и закрываются, поэтому никакой специальной обработки не требуется. Из вашего описания звучит так: вот что происходит: если ваша программа умерла из-за сигнала, вы не увидите сброс.

У меня проблемы с пониманием, в чем именно проблема.

Если вы просто пытаетесь найти удачное средство между частой очисткой и выводом по умолчанию с полной буферизацией, тогда, возможно, вам нужна буферизация строки:

setvbuf(stream, 0, _IOLBF, 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...