Задача следующая:
Необходимо как можно быстрее записать данные в лог-файл со сбросом буферов и продолжить выполнение программы (цикл).
Что в данном случае предпочтительней, пользоваться fopen, fflush и т.д. или использовать Win API функции?
Для более наглядного представления:
while(IsWork) {
result = myfunc();
if (!result) {
fprintf(log_file, "Lod Data...");
fflush(log_file);
}
}
myfunc() возвращает управление только при определенных условиях, о которых она сообщает возвратом TRUE/FALSE, далее это мне надо зафиксироваль в логе и как можно быстрее снова вызвать myfunc().
В одну единицу времени (допустим 1 сек) myfunc() может вообще не возвратить управление, а может и отработать сотню раз, все эти 100 раз нужно оперативно зафиксировать в логе с наименьшей задержкой перед следующим шагом цикла while().
Как корректней поступить в данной конкретной задаче?
Здравствуйте, Bariy, Вы писали:
B>Необходимо как можно быстрее записать данные в лог-файл со сбросом буферов и продолжить выполнение программы (цикл).
B>Что в данном случае предпочтительней, пользоваться fopen, fflush и т.д. или использовать Win API функции?
[skipped]
B>Как корректней поступить в данной конкретной задаче?
Как здесь уже не раз обсуждалось — буферизация невыровненых данных на уровне user-application существено эффективней ядерной. Т.к. для помещения данных в буфер требуется намного меньше операций.
Рекомендуемый буфер как выяснилось 256к, 64к, или 128к (на сколько я помню лучше 256, хотя на первый взгляд более логичным кажется 64).
Соответственно вам нужно либо устанавливать объем буфера с помощью
setvbuf(log_file, your_buffer, _IOFBF, 256*1024);
А
fflush() делать
за пределами цикла. Иначе уж лучше без буферизации.
Что касается времени отклика — тут смотря что вым ценнее. Если можно небольшую часть сообщений при большой нагрузке потерять — делайте циклический буфер и все туда складывайте.
Управление позициями чтения и записи сделать можно через
InterlockedExchangeAdd(). Тогда быстренько складываете сообщение в буфер и сигналите Event (лучше не каждый раз),
а другой поток по Event'у просыпается и выписывает все данные, пока буфер не опустошится. Причем выписывание для пущей производительности тоже буферизировать.
А если нельзя терять ничего — ввести еще 2й Event для сигнализации того, что часть данных во 2м потоке уже выписана и ждать на нем в 1м если при попытке записать в буфер окажтся, что места уже нет.
Или делать все в одном потоке и пользоваться Overlapped Write для выписывания из своего буфера при его заполнении. В этом случае нужно заводить 2 одинаковых буфера и если сообщене не влазит цликом, вписывать часть и отправлять на запись, а продолжать складывать сообщения уже во второй. А как он заполнится — снова помнять местами. Ну и не забыть все таки перед очередным обменом проверить, что запись завершилась