Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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 вся ветка

Форум: "Прочее";
Текущий архив: 2007.05.06;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.043 c
15-1175809511
sv_sergik
2007-04-06 01:45
2007.05.06
Улучшеный IDE


2-1176416482
Могот
2007-04-13 02:21
2007.05.06
MediaPlayer прикол со звуком в видео


3-1171802805
Rav
2007-02-18 15:46
2007.05.06
TAdoQuery - "обновление"??? при удалении записи


11-1155058319
Stals
2006-08-08 21:31
2007.05.06
Как прицепить словарь от Microsoft Office


15-1175927960
ArMellon
2007-04-07 10:39
2007.05.06
Как экспортировать ветку рееста в файл и обратно импортировать





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский