Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.11.2011, 14:53   #1
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию Как правильно организовывать лог-файл в многопоточных приложениях?

Доброго времени суток!

Вопрос в следующем:
как правильно организовать ведение лога в многопоточном приложении?

Передомной n число проблем:
1. Хреналион потоков одновременно вызовет сброс данных в файл.
2. Как и когда организовывать сброс данных в файл?
3. как вообще правильно сбрасывать данные в файл?

Сайчас у меня это организовано следующим образом:
Есть некий обьект TObject, далее есть хранилище этих обьектов TList.
Всё это связано с ListView(Ну отображение), сброс в файл происходит после каждого вызова "добавить запись в лог".

НО думаю хранение хреналиардов Object в Tlist пагубно сказывается на ОЗУ ПК где работает программа. Особенно, когда прорамма работает несколько месяцев.

В общем я в тупике по поводу этого...
Сейчас пытаюсь связать всё это дело с XML файлами.

А задачи такие:
1. собирать и сохранять всю информацию.
2. ничего не растерять при падении программы.(Программа навернулась, однако в логе данные есть хотябы за прошедшие 5 секунд).

Последний раз редактировалось Человек_Борща; 26.11.2011 в 14:55.
Человек_Борща вне форума Ответить с цитированием
Старый 26.11.2011, 15:08   #2
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

Любите вы задавть одинаковые вопросы раз в пол-года )
Я уже приводил этот код. За последние пол-года в нём только допилена совместимость с x64. Типы int и unsigned объявлены как 32/64, в зависимости от проца.


Код:
var
  g_logOL: array[byte] of OVERLAPPED;		// array of OL
  g_logOLOffs: int;				// offset of next OL operation
  g_logOLEvents: array[byte] of tHandle;	// array of OL event handles
  g_logOLBufs: array[byte] of pointer;		// array of OL buffers
  g_logOLBufsSz: array[byte] of int;		// array of OL buffer sizes
  g_logOLCount: int;				// number of OLs

// --  --
function incMT(var v: int; delta: int): int;
begin
  result := InterlockedExchangeAdd(v, delta);
end;

// --  --
function write2file(handle: tHandle; var offset: int; buf: pointer; len: unsigned): bool;
var
  i: DWORD;
  OL: POVERLAPPED;
  ofs: unsigned;
begin
  result := false;	//
  if ((0 < len) and (nil <> buf)) then begin
    //
    ofs := incMT(offset, len);
    //
    // find non-pending OL
    i := 0;
    if (0 < g_logOLCount) then begin
      //
      i := WaitForMultipleObjects(g_logOLCount, PWOHandleArray(@g_logOLEvents), false, 10);	// do not wait for too long, better create new OL
      if (i < WAIT_OBJECT_0 + unsigned(g_logOLCount)) then
	OL := @g_logOL[i - WAIT_OBJECT_0]
      else
	OL := nil;	// all are busy
    end
    else
      OL := nil;
    //
    if ((nil = OL) and (g_logOLCount <= high(g_logOL) - low(g_logOL))) then begin
      //
      i := low(g_logOL) + incMT(g_logOLCount, 1);
      g_logOLEvents[i] := CreateEvent(nil, false, false, nil);	// auto-reset event
      g_logOL[i].hEvent := g_logOLEvents[i];
      //
      OL := @g_logOL[i];
    end;
    //
    if (nil <> OL) then begin
      //
      if (int(len) > g_logOLBufsSz[i]) then begin
	//
	reallocMem(g_logOLBufs[i], len);
	g_logOLBufsSz[i] := len;
      end;
      //
      move(buf^, g_logOLBufs[i]^, len);
      //
      OL.Offset := ofs and $FFFFFFFF;
      {$IFDEF CPUx64 }
      OL.OffsetHigh := ofs shr 32;
      {$ELSE }
      OL.OffsetHigh := 0;
      {$ENDIF CPUx64 }
      //
      result := WriteFile(handle, g_logOLBufs[i], len, nil, OL);
      if (not result and (ERROR_IO_PENDING = GetLastError())) then
	result := true	// report no error
      else
	SetEvent(OL.hEvent);
      //
    end;
  end;
end;

// --  --
procedure releaseOLs();
var
  i: int;
  w: unsigned;
begin
  if (0 < g_logOLCount) then begin
    //
    WaitForMultipleObjects(g_logOLCount, PWOHandleArray(@g_logOLEvents), true, 3000);
    //
    i := 0;
    while (i < g_logOLCount) do begin
      //
      w := WaitForSingleObject(g_logOLEvents[i], 10);
      if (WAIT_OBJECT_0 = w) then begin
	//
	CloseHandle(g_logOLEvents[i]);
	reallocMem(g_logOLBufs[i], 0);
      end;
      //
      inc(i);
    end;
    //
    g_logOLCount := 0;
  end;
end;
Вызов write2file() осуществляется в любое время из любого потока. Предполагается, что handle — это открытый хендл вашего лог файла. Всё.

Пример добавления строки в конец лог-файла:

Код:
	  write2file(g_infoLogFileHandle, g_logOLOffs, @data[1], length(data) * sizeOf(data[1]));
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."

Последний раз редактировалось veniside; 26.11.2011 в 15:20.
veniside вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как правильно открыть php файл? shevron PHP 2 07.08.2011 15:33
Прога с/с++, она должна анализировать лог файл hacker007 Помощь студентам 5 27.05.2011 16:35
скрипт получает post запросы и логирует в лог файл quarty Помощь студентам 2 01.02.2011 17:39
Как правильно организовать сохранение в файл delphi JK0 Помощь студентам 1 21.12.2010 21:14
Delphi.Как организовывать чтение из файла и отображение его в списке-ListBoxе. FireflyJuillet Помощь студентам 0 20.05.2010 00:54