Работа с файлом, RTL или Win API?
От: Bariy  
Дата: 26.03.06 06:05
Оценка:
Задача следующая:

Необходимо как можно быстрее записать данные в лог-файл со сбросом буферов и продолжить выполнение программы (цикл).

Что в данном случае предпочтительней, пользоваться 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().

Как корректней поступить в данной конкретной задаче?
Re: Работа с файлом, RTL или Win API?
От: Alter_ Украина http://alter.org.ua
Дата: 26.03.06 09:46
Оценка: 5 (1)
Здравствуйте, 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 одинаковых буфера и если сообщене не влазит цликом, вписывать часть и отправлять на запись, а продолжать складывать сообщения уже во второй. А как он заполнится — снова помнять местами. Ну и не забыть все таки перед очередным обменом проверить, что запись завершилась
--
Alter, http://alter.org.ua
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.