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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 09.05.2011, 20:21   #11
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

это понятно. У меня многопоточное приложение создающее заранее не известное кол-во потоков. Семафор релизовывать в мотоде обращения к файлу а в тотоках вызывать этот метод? или как-то по другому?
Человек_Борща вне форума Ответить с цитированием
Старый 09.05.2011, 23:07   #12
ReportCube
Форумчанин
 
Аватар для ReportCube
 
Регистрация: 11.03.2011
Сообщений: 426
По умолчанию

Вставляете "как есть" в модуль. Из любого потока отправляете в процедуру/функцию записи в лог. Семафор стоит на страже, если один поток пишет, то второй будет ждать, пока откроется семафор. Как только семафор открыт - захват семафора, запись в файл, открытие семафора для следующего и выход из процедуры/функции.
ReportCube вне форума Ответить с цитированием
Старый 09.05.2011, 23:16   #13
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

т.е. согласно вашему коду я могу спокойно сделать вот так:
Код:
var
 SemHandle:Thandle;

function AddSystemLog(aStr:string);
var
  Ts:TstringList;
   W:WORD;
begin
  W:=WaitForSingleObject(SemHandle,INIFINITE);
    try
      If (W = WAIT_OBJECT_0) then
      begin
         Ts.add(aStr);
         Ts.SaveToFile('Log.txt');
      end;
     finally
      ReleaseSemaphore(SemHandle, 1, nil);
      FreeAndnil(Ts);
    end;
end;


Initialization
 SemHandle := CreateSemaphore(nil, 1, 1, nil);

Finalization
 CloseHandle(SemHandle);
? И потом использовать эту процедуру в потоках небоясь жучков?
Человек_Борща вне форума Ответить с цитированием
Старый 09.05.2011, 23:19   #14
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

А семафор-то здесь зачем?

Код:
uses
  SyncObjs;

var
  FLogCS: TCriticalSection;

function AddSystemLog(const AStr: String);
begin
  FLogCS.Enter;
  try
    // добавляем в лог
  finally
    FLogCS.Leave;
  end;
end;

initialization
  FLogCS := TCriticalSection.Create;
finalization
  FreeAndNil(FLogCS);
end.
Это - только пример! В реальном коде FLogCS должно быть частью объекта логгирования.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 10.05.2011, 01:14   #15
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Цитата:
FLogCS должно быть частью объекта логгирования.
можно это, пожалуйста, пояснить подробнее?
Человек_Борща вне форума Ответить с цитированием
Старый 10.05.2011, 01:27   #16
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Можно.

Сердце должно качать кровь, а лёгкие - воздух. А не наоборот. И уж тем более не мешанина как в амёбе.

Это - суть ООП, да и вообще любого структурирования.

Обеспечение атомарности доступа в данном случае - задача лога. Вот он её и должен выполнять. А не кто-то там ещё, сбоку навешанный и костылями подпоротый.

Пример с плагинами из соседней темы смотрел? Та же ошибка: работу с плагинами должен делать менеджер плагинов. А у тебя он (менеджер) только контейнером был, а работа с плагинами была размазана по программе.

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

Это и есть грамотное проектирование.

Простейший вариант мог бы быть таким:

Код:
uses
  SyncObjs;

type
  TLog = class(TStringList)
  private
    FLogCS: TCriticalSection;
  public
    constructor Create;
    destructor Destroy; override;
    function Add(const S: String): Integer; override;
  end;

constructor TLog.Create;
begin
  inherited;
  FLogCS := TCriticalSection.Create;
end;

destructor TLog.Destroy;
begin
  FreeAndNil(FLogCS);
  inherited;
end;

function TLog.Add(const S: String): Integer;
begin
  FLogCS.Enter;
  try
    Result := inherited Add(S);
  finally
    FLogCS.Leave;
  end;
end;
Но и это ещё не идеально.

Самое правильное - создать чистый объект. TStringList использовать внутри, как поле. А наружу выставить только Add, Clear и SaveToFile (ну и может ещё кого полезного).

Я имею ввиду, что странно выглядит лог, у которого есть Delete и Exchange, а также возможность ассоциировать объекты со строками.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ведение лога изменений в базе erzi Microsoft Office Access 6 02.02.2011 21:55
Ведения лога программы! $T@LKER Компоненты Delphi 2 09.09.2010 15:36
Как лучше включать режим лога? Alex Cones Общие вопросы Delphi 11 12.07.2010 00:07
Способы ведения файла-лога Norfolk Общие вопросы Delphi 2 14.06.2007 20:47