Страницы: 1 2 вся ветка
Форум: "Прочее";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2007.05.06;
Скачать: [xml.tar.bz2];




Вниз

LDSLogger 


Loginov Dmitry ©   (2007-04-09 19:01) [0]

Вот накатал небольшой модулек для ведения логов в многопоточном приложении(ях).

Описание:


Выполняет надежное потокобезопасное логгирование текстовых данных
с возможностью ограничения размера LOG-файла, либо с применением часто
используемой техники переименования старых LOG-файлов. Операцию записи в
файл можно защитить критической секцией (не самый надежный способ, так
как одному LOG-файлу не может соответствовать более одной критической секции,
тем более при ведении одного лога из нескольких приложений это может запросто
привести к ошибке ввода-вывода). Другой способ защиты - использование объекта
синхронизации "мьютекса". Данный способ защиты используется по-умолчанию
и менять его без нужды не следует. Данный способ работает одинаково надежно
как внутри одного приложения (в многопоточном режиме), так и с приложениями,
работающими независимо друг от друга. При возникновении ошибки ввода-вывода
исключение будет перехвачено и погашено (однако о нем вы все-равно узнаете,
так как будет сгенерирован короткий звуковой сигнал функцией Windows.Beep()).
Вы можете указать программе, чтобы она автоматически добавляла в лог ID текущего
процесса и потока. Вы можете изменить формат вывода времени сообщения. Вы можете
определить свойство DefaultPrefix, благодаря которому можно узнать, какая
часть вашей программы осуществляла запись в лог того или иного текста.


Не претендую на универсальность модуля, и более существенно развивать его не собираюсь. Если кто захочет скачать, то ссылка вот:
http://matrix.kladovka.net.ru/download.php?getfilename=uploads/other/ldslogger.zip

Вроде есть какая-никакая польза, ну и выложил, чтоб в забвение не ушел.



Суслик ©   (2007-04-10 10:23) [1]

в любом случае убери слово "надежное" :)



Суслик ©   (2007-04-10 10:40) [2]

не проверяешь результат выполнения
FMutexHandle := CreateMutex(nil, False, PChar(GenerateMutexName));

в остальном вроде нормально.



Суслик ©   (2007-04-10 10:43) [3]

Хотя нет :)
есть у тебя ошибка :)
многопоточной работы.

Lock у тебя неверно написан. перепиши.

создавай крит. секцию в конструкторе, а не по требованию.
тоже самое с мьютексом.



Суслик ©   (2007-04-10 10:47) [4]

число скачиваний уже 12!!! одумайтесь, люди.

-------

если серьезно, то советую тебе поизучать серьезный многопоточный код.
любой :) только качественного производителя. да хоть тот же TThread. Тогда таких детских ошибок делать не будешь.

С наилучшими (честно) пожеланиями.



Loginov Dmitry ©   (2007-04-10 10:47) [5]

Знаю. При работе с файлами нет ничего надежного :)
А если выставить read-only, то и логгирования вообще не произойдет никакого.

А "надежное" я имел ввиду в плане ведения одного лога сразу несколькими приложениями. Может быть кому-то покажется интересной идея (пусть древнейшая) защиты записи в файл мьютексом, имя которого формируется путем обработки имени файла. Другого, более надежного и простого способа защиты я не придумал :).



Суслик ©   (2007-04-10 10:52) [6]

дима, извини, терперь это слово не могу, но завязывай с ламерством :)
честное слово - ну зачем себя позорить то. ты даже не понял, что я тебе сказал.

и вообще - я не мать тереза. сам учись.

(блин, сейчас же еще обиду затаит :) )

---------
дима, скажи только честно - это не развод? :)



Суслик ©   (2007-04-10 10:53) [7]

не думаю, что многие захотят смотреть твой код, поэтому приведу его кусок. путь тоже кто-нить покритикует тебя :)

procedure TLDSLogger.Lock;
begin
 if UseCritSect then
 begin
   if FCritSect = nil then
     FCritSect := TCriticalSection.Create; // LoL :)

   FCritSect.Enter;
 end else
 ...
 <skiped>
end;


вот такая у нас процедура lock



Суслик ©   (2007-04-10 10:56) [8]

hint
1. возьми этот код
2. распечатай в 2х экземплярах.
3. положит рядом.
4. поводи пальчиком по одной страничке - это один поток.
5. поводи пальчиком по другой страничке - это другой поток.
6. имей в виде, что выполнение потока может быть прервано в любой момент.

все сам поймешь.

еще hint - в результате у тебя каждый поток может ждать СВОЕГО экземпляра критической секции :) какая тут защита? да еще надежная.

ЗЫ И что я так завелся - все равно весь мир не научишь программировать :)



Суслик ©   (2007-04-10 10:58) [9]

и еще, дима, имей в виду, что часто при приеме на работу анализируется публичное присутствие человека в сети. если я бы увидел такой код и твои комментарии, то я бы ни секунды не продолжал бы процесс приема тебя к себе на работу: прервал бы стразу.

одним словом - поправь :)
тебе же лучше.



Loginov Dmitry ©   (2007-04-10 11:05) [10]

> если серьезно, то советую тебе поизучать серьезный многопоточный
> код.
> любой :) только качественного производителя. да хоть тот
> же TThread. Тогда таких детских ошибок делать не будешь.


Модуль будет правиться по мере наступления на грабли, связанные с неполным учетем особенностей многопоточного приложения. Если такие грабли будут, то может быть перепишу данный модуль. Но пока не вижу практической ситуации, где бы из-за отсутствия проверки GetLastError программа работала бы менее надежно. Насчет критической секции - согласен. Есть ненулевая вероятность того, что при первой попытке записи в лог сразу из нескольких потоков объект критической секции будет создан несколько раз. В этом случае поимеем и утечку памяти и ошибку ввода вывода.
В случае повторного создания мьютекса, имхо, даже ошибка ввода-вывода произойти не должна.
Чесно скажу, ошибка есть и в вызове функции GetFileSize() до CloseFile(), так как до CloseFile() вывод в файл кэшируется, и фактический размер файла не соответствует тому, что выдаст GetFileSize().



Loginov Dmitry ©   (2007-04-10 11:06) [11]

> дима, извини, терперь это слово не могу, но завязывай с
> ламерством :)
> честное слово - ну зачем себя позорить то. ты даже не понял,
> что я тебе сказал.
>
> и вообще - я не мать тереза. сам учись.


Я твои посты прочитал уже после отправки [5]. Ну ничего. Не обиделся.



Loginov Dmitry ©   (2007-04-10 11:08) [12]

то есть я снача прочел [1], затем отправил [5], а уж потом обнаружил посты [2] - ...



Loginov Dmitry ©   (2007-04-10 11:10) [13]

> и еще, дима, имей в виду, что часто при приеме на работу
> анализируется публичное присутствие человека в сети. если
> я бы увидел такой код и твои комментарии, то я бы ни секунды
> не продолжал бы процесс приема тебя к себе на работу: прервал
> бы стразу.
>
> одним словом - поправь :)
> тебе же лучше.


Ладно, подправлю, это уже дело принципа.



Суслик ©   (2007-04-10 11:10) [14]


> Чесно скажу, ошибка есть и в вызове функции GetFileSize()
> до CloseFile(), так как до CloseFile() вывод в файл кэшируется,
> и фактический размер файла не соответствует тому, что выдаст
> GetFileSize().

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



Loginov Dmitry ©   (2007-04-10 11:18) [15]

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



Суслик ©   (2007-04-10 11:20) [16]

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



Игорь Шевченко ©   (2007-04-10 11:47) [17]


> Я совершенно не искушенный человек в области многопоточности.
>  Не было у меня соответствующей практики


А Рихтера не судьба почитать ?



Loginov Dmitry ©   (2007-04-10 11:52) [18]

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



Игорь Шевченко ©   (2007-04-10 12:06) [19]


> Практикой в использовании многопоточности я считаю - разработка
> серьезного коммерческого приложения, в котором одновременно
> крутятся десятки потоков и любая ошибка карается


Ну зачем же так сурово. Кроме того, мне не представляется серьезное коммерческое приложение с такой функциональностью и тем более, написанное на Delphi - я просто не вижу области его применения.



Loginov Dmitry ©   (2007-04-10 12:25) [20]

> Ну зачем же так сурово. Кроме того, мне не представляется
> серьезное коммерческое приложение с такой функциональностью
> и тем более, написанное на Delphi - я просто не вижу области
> его применения.


Первое, что приходит в голову - организация магазина с несколькими десятками касс, с одним СОМ-сервером БД, взаимодействие между которыми происходим с помощью MIDAS. Каждому клиенту в данном случае будет соответствовать по меньшей мере один поток, а вот ошибки программы в таких приложениях могут обойтить довольно дорого. Как магазину, так и программисту, который можеть и не додуматься, как последствия таких ошибок можно исправить.



Loginov Dmitry ©   (2007-04-10 12:32) [21]

Кстати, я подправил модуль LDSLogger. Вроде все что можно было учел. Сейчас крит. секция создается в конструкторе и во всех случаях защищает запись в файл. При установке параметра UseMutex (устанавливается по умолчанию) происходит дополнительная защита записи в файл. Критическая секция защищает теперь не только запись в файл, но также и другие операции, выполнение поторых может повлиять на запись в файл. Теперь я думаю, модуль не подведет даже в самых жестких условиях (если он конечно сможет устоять критике Дмитрия :)



SlymRO ©   (2007-04-10 12:35) [22]

почему string параметры не const? непорядок



Игорь Шевченко ©   (2007-04-10 12:36) [23]


> Первое, что приходит в голову - организация магазина с несколькими
> десятками касс, с одним СОМ-сервером БД, взаимодействие
> между которыми происходим с помощью MIDAS


Пример здорово надуманный, потому что систем автоматизации торговли как звезд на небе и с проблемами многопоточности они не сталкиваются.



Loginov Dmitry ©   (2007-04-10 12:43) [24]

> почему string параметры не const? непорядок


А в каком месте для них необходим const?



Суслик ©   (2007-04-10 12:45) [25]


> А в каком месте для них необходим const?

оптимальней просто с const - не создается локальная копия :)
CPU посмотри.



Loginov Dmitry ©   (2007-04-10 12:47) [26]

> оптимальней просто с const - не создается локальная копия
> :)
> CPU посмотри.


Спорно. Копия будет создана только при обращении к элементу строки в виде S[i]. Поэтому про оптимальность - это Вы зря.



SlymRO ©   (2007-04-10 12:57) [27]

Loginov Dmitry ©   (10.04.07 12:47) [26]
без const как минимум вызывает LStrAddRef со const нет...



Суслик ©   (2007-04-10 13:05) [28]


>  [26] Loginov Dmitry ©   (10.04.07 12:47)

дима, зачем ты это делаешь?
зачем себя смешно вести?
ну возьми прежде чем постить что-то разберись.



Loginov Dmitry ©   (2007-04-10 13:20) [29]

> дима, зачем ты это делаешь?
> зачем себя смешно вести?
> ну возьми прежде чем постить что-то разберись.


В каком месте это смешно? Я разбирал в определенной степени работу со строками в Дельфи. И просто говорю, что Const в данном случае в плане скорости никаких преимуществ не даст. А что Вам кажется смешным - не понятно. Читая [28] мне самому смешно стало. Не за себя.



Суслик ©   (2007-04-10 13:33) [30]


> [29] Loginov Dmitry ©   (10.04.07 13:20)

ну бог тебе в помощь.
я начинаю понимать почему старшие товарищи в топиках с твоим участием не светятся :)



Loginov Dmitry ©   (2007-04-10 13:37) [31]

> я начинаю понимать почему старшие товарищи в топиках с твоим
> участием не светятся


Я стараюсь не заводить лишних топиков (если и завожу то не чаще раза в месяц).



Rouse_ ©   (2007-04-10 13:54) [32]


> Суслик ©  

Димыч, ты чего на человека набросился то? :)
Ну нет у него опыта, научится же...



Игорь Шевченко ©   (2007-04-10 13:58) [33]

Rouse_ ©   (10.04.07 13:54) [32]


> Ну нет у него опыта, научится же...


"Может, он потом пожарником станет"
(с) Волшебная сила искусства



db2admin   (2007-04-10 14:01) [34]

Loginov Dmitry ©
Ты не кипятись спокойно подумай, проверь что предлагается.
Конечно обидно когда твою супер прогу критикуют, но создовая пост этого ты и хотел.



Manic Mechanic ©   (2007-04-10 14:07) [35]

>> Ну нет у него опыта, научится же...

Он упорно учился на ошибках ... Но его обошли те, кто учился по книгам. (с)



Loginov Dmitry ©   (2007-04-10 14:12) [36]

> Ты не кипятись спокойно подумай, проверь что предлагается.
> Конечно обидно когда твою супер прогу критикуют, но создовая
> пост этого ты и хотел.


Я исправил модуль согласно с замечаниям Дмитрия. После этого по теме многопоточности замечаний не было (видимо, Дмитрий не нашел в чему придраться (скорее не стал этим заниматься), и тут SlymRO начал придираться к отсутствию пресвоутого Const, наличие которого ускорило бы выполнение программы аж на пол-такта.

Вот этот код без Const:
constructor TLDSLogger.Create(AFileName: string);
begin
 FCritSect := TCriticalSection.Create;
 FMaxFileSize := MAX_LOGFILE_SIZE;
 FDateTimeFormat := DATE_TIME_FORMAT;
 FUseMutex := True;
 FileName := AFileName;
 FEnabled := True;
 FCanWriteLogWords := True;
 FClearOldLogData := True;
end;

Ну зачем нужно было к нему придираться?



Суслик ©   (2007-04-10 15:13) [37]


> программы аж на пол-такта.

о, блин, опытный какой - такты умеет считать.
сравни (я не поленился, а вот ты поленился это сделать)

{$o+}
procedure TestConst(const S: String);
begin
  ShowMessage(S);

(*

Unit1.pas.38: ShowMessage(S);
0046B66C E8E391FCFF       call ShowMessage
Unit1.pas.55: end;
0046B671 C3               ret
0046B672 8BC0             mov eax,eax

*)
end;

procedure TestNoConst(S: String);
begin
  ShowMessage(S);

(*

Unit1.pas.52: begin
0046B674 55               push ebp
0046B675 8BEC             mov ebp,esp
0046B677 51               push ecx
0046B678 8945FC           mov [ebp-$04],eax
0046B67B 8B45FC           mov eax,[ebp-$04]
0046B67E E8B994F9FF       call @LStrAddRef
0046B683 33C0             xor eax,eax
0046B685 55               push ebp
0046B686 68AFB64600       push $0046b6af
0046B68B 64FF30           push dword ptr fs:[eax]
0046B68E 648920           mov fs:[eax],esp

Unit1.pas.53: ShowMessage(S);
0046B691 8B45FC           mov eax,[ebp-$04]
0046B694 E8BB91FCFF       call ShowMessage

Unit1.pas.84: end;
0046B699 33C0             xor eax,eax
0046B69B 5A               pop edx
0046B69C 59               pop ecx
0046B69D 59               pop ecx
0046B69E 648910           mov fs:[eax],edx
0046B6A1 68B6B64600       push $0046b6b6
0046B6A6 8D45FC           lea eax,[ebp-$04]
0046B6A9 E8DA8FF9FF       call @LStrClr
0046B6AE C3               ret

*)
end;



Loginov Dmitry ©   (2007-04-10 15:33) [38]

Ну и что здесь нового. Понятно, что выполняется инкремент и декремент счетчика ссылок. Ошибся, каюсь. Не пол такта, а чуть больше. Второй вариант - оптимальнее. Я давно про это знаю и с этим не спорил. Но свой пост [25] прочитайте же наконец! Какая локальная копия? Локальная копия чего?



default ©   (2007-04-10 15:42) [39]

автор, ты действуешь недальновидно!
ну кто после таких веток будет без смеха смотреть на твои посты о усоврешненствования матричной системы и тем более использовать её
хотя бы ник что-ли сменил-бы...



Суслик ©   (2007-04-10 16:35) [40]

:)




Страницы: 1 2 вся ветка
Форум: "Прочее";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2007.05.06;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.86 MB
Время: 0.098 c
15-1175862979     palva                 2007-04-06 16:36  2007.05.06  
Пятница. Невезучая теорема Стюарта.


15-1175790951     Pazitron_Brain        2007-04-05 20:35  2007.05.06  
Извечный спор: микроядро или монолитное?


15-1176019813     easy                  2007-04-08 12:10  2007.05.06  
Янис Прасол (aka Gero)


15-1175855240     Gorlum                2007-04-06 14:27  2007.05.06  
Как протестировать компьютер


15-1175977895     vasIZmax              2007-04-08 00:31  2007.05.06  
Как правильно писать программу?!