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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 21.10.2011, 01:48   #11
Lime
Форумчанин
 
Аватар для Lime
 
Регистрация: 10.02.2009
Сообщений: 815
По умолчанию

То есть в идеале всё выглядит так:
[1]Основной поток программы, заботится о старте/паузе/остановке/настройках и прочих мелочах
[n]Поток обработчик, производит обработку информации, формирует промежуточные результаты работы(сообщения)
[n]Поток работающий с критическими секциями непосредственно добавляющий сообщения потока обработчика в общий лог? (который, к примеру, при завершении программы сохраняется в файл)

Верно?)
Lime вне форума Ответить с цитированием
Старый 21.10.2011, 02:13   #12
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,430
По умолчанию

Крит. секция стоит конвеер из вызывающих метод, обьектов.
Позволяя работать только первому вызвавшему метод(момент CriticalSection.Enter), обьекту, остальные строятся в очередь за ним, в том порядке, в котором они вызвали этот метод.
Далее первый вываливается из очереди после CriticalSection.Leave, уступая след. после себя обьекту. Отработав первый, породолжает свой код, и дойдя снова до метода с крит. секцией, будет "послан" в конец очереди.

Очень похоже на то, как работает стёк.

З.Ы. надеюсь крит. секция обьвлена как глоб. обьект?

Последний раз редактировалось Человек_Борща; 21.10.2011 в 02:17.
Человек_Борща вне форума Ответить с цитированием
Старый 21.10.2011, 02:29   #13
Lime
Форумчанин
 
Аватар для Lime
 
Регистрация: 10.02.2009
Сообщений: 815
По умолчанию

Цитата:
З.Ы. надеюсь крит. секция обьвлена как глоб. обьект?
Естественно.
Вы объяснили то-же что и я, в одном из своих предыдущих постов, но более доходчиво

Ну а на счет идеального варианта (в теории) это схоже с постом #11?
Чтобы поток обработчик не ждал своей очереди в крит.секции а продолжал работать дальше возлагая работу по добавлению сообщения в лог другому потоку?
Lime вне форума Ответить с цитированием
Старый 21.10.2011, 02:35   #14
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,430
По умолчанию

хм как вариант, реализовать класс ведения таким образом чтобы,
потоки просто передавали сообщения которые надо записать, и продолжали работу.
А класс лога просто писал бы их без остановки.
Но и тут без крит. секции никак т.к. все делает 1 обьект, а к нему обращаются много.
тут все сводится к методу добовления сообщения в обьект, а не в файл.
А класс лога просто пишет сообения в лог-файл на диске не перставая, и удаляет записанную строку из "временного" места хранения.

1. рабочий поток передаёт логирующему сообщение, а сам продолжает работать.
2. логирующий поток пишет его не сразу, у него есть TStrings куда пишется эта строка.
Вот тут-то и нужно сделать крит. секцию(Enter, leave) т.к. обькт 1 а к нему много обращений.
3. Логирующий поток не заботиться о том чтобы писать переданное ему сразу же, а просто по строчно пишет сообщения из этого TStrings, в файл и сохраняет его, а затем удаляет только что записаное из временного хранилища.

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

хотя я понятия не имею как это реализовать. так чтобы класс лога при добовлении сообщения не инициbрировал его запись в файл.
А тупо в др. месте проверял наличия сообщения на обработку и писал его.

мб это из-за того что сейчас 2 часа ночи(у меня)

Последний раз редактировалось Человек_Борща; 21.10.2011 в 02:44.
Человек_Борща вне форума Ответить с цитированием
Старый 21.10.2011, 02:48   #15
Lime
Форумчанин
 
Аватар для Lime
 
Регистрация: 10.02.2009
Сообщений: 815
По умолчанию

Чтобы постоянно не дёргать диск я думаю "LogManager" должен набирать некоторое кол-во сообщений (скажем 200) и после этого записывать их в файл. И при командах завершения/паузы/прочих так-же записывать в файл, очищая временное хранилище.

Правда это немного другая тема, основной вопрос (теоретический) был про работу с глобальными переменными из потоков и, возможно, наиболее производительные/правильные варианты реализации

add:
Цитата:
хотя я понятия не имею как это реализовать
Реализовать то не проблема Главное выяснить теоретически лучший вариант!

Реализовать, как мне кажется можно очень легко!
Код:
procedure TPortListener.PrintSyncMessage(MSG:string);
var //Стоит ли объявлять его тут? О_о
begin
LoggerThread := TLoggerThread.Create(True);
LoggerThread.FreeOnTerminate := True;
LoggerThread.Priority := tpNormal;
LoggerThread.LMessage := MSG;
LoggerThread.Resume;
end;
(писал по памяти)
Суть: поток обработчик создает поток работающий с крит.секцией и продолжает работу, созданный поток (не занятый ничем кроме добавления сообщения) ждёт своей очереди и выполняет работу, освобождая память при завершении (LoggerThread.FreeOnTerminate := True. По идее LoggerThread это всего-лишь хэндл, верно? Чет я запутался

Последний раз редактировалось Lime; 21.10.2011 в 03:03.
Lime вне форума Ответить с цитированием
Старый 21.10.2011, 03:01   #16
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,430
По умолчанию

Код:
uses
  SyncObj;

var
  CS:TCriticalSection; 


procedure TLogRecorder.create;
begin
  CS:=TCriticalSection.Create;
end;

procedure DoMessage(aMsg:string);
begin
  CS.Enter; 
      {Здесь хоть на ушах стой...}
  CS.Leave;
end;

procedure TLogRecorder.Destroy;
begin
  FreeAndNil(CS);
end;

Последний раз редактировалось Человек_Борща; 21.10.2011 в 03:07.
Человек_Борща вне форума Ответить с цитированием
Старый 21.10.2011, 04:31   #17
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

А занафига нужен глобальный логер? Сделайте логер per-thread. И никакой синхронизации не надо.

Лучшая синхронизация - та, которую не нужно выполнять

Но если так нужно именно глобальный - посмотрите в сторону связанных списков и lock-free механизмов доступа.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 21.10.2011, 18:39   #18
Lime
Форумчанин
 
Аватар для Lime
 
Регистрация: 10.02.2009
Сообщений: 815
По умолчанию

"Логгер" должен записывать информацию не только из этих потоков, при том минимально затрагивать производительность тех или иных процессов (имеется ввиду функций всей программы).

Ну а реализация, которую мы ненароком обсуждаем, мне наиболее понятна и есть небольшой опыт в создании аналогичного
Lime вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Многопоточность. Ошибка продолжения (возобновления) потока. RobSys Общие вопросы Delphi 8 01.03.2011 01:30
Многопоточность. Ведение логов из каждого потока. Проблемы Человек_Борща Общие вопросы Delphi 3 07.01.2011 18:22
Доступ к функциям и структурам из потока MAIN_ELF Общие вопросы C/C++ 2 04.10.2010 15:08
Многопоточность с глобальной переменной Шульц Общие вопросы Delphi 1 30.01.2010 18:19
Имя переменной как переменная. Как получить доступ к такой переменной? Denni Microsoft Office Access 8 02.04.2009 10:06