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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 19.10.2011, 19:00   #1
Lime
Форумчанин
 
Аватар для Lime
 
Регистрация: 10.02.2009
Сообщений: 815
Вопрос Многопоточность. Безопасный доступ к переменной/функции из потока.

Всем доброго времени суток!
Делаю многопоточное приложение (в дебаг моде присутствует консолька).
Суть: каждый поток при некоторых событиях и результатах работы должен добавлять в общий лог сообщения и менять некоторые переменные.
Во многих источниках пророчат страшные муки тем кто не до конца обдумал работу с вводом/выводом данных из потока (с чтением записью переменных в общем) посему вопрос: Хватит ли для подобных действий критической секции?
а именно в
Код:
var cs:TCriticalSection;
а в одном из метотдов потока
Код:
cs.Enter;
// работа с внешней переменной
cs.Leave;
Или-же доступ к методам TCriticalSection так-же является проблемным местом?
P.S. как я понял Synchronize более "актуален и применим" в оконных приложениях?

Спасибо!
Lime вне форума Ответить с цитированием
Старый 19.10.2011, 19:08   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Да все нормально, для этого и придуманы критические секции
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 20.10.2011, 08:28   #3
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Synchronize - это более сильное ограничение, чем критическая секция.

В большинстве случаев достаточно критической секции. При условии, конечно, что вы правильно её используете.

Но это я руками в воздухе помахал. Кокретику, не видя вашего кода, не скажешь.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 20.10.2011, 08:28   #4
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Посмотрите ещё: http://www.gunsmoker.ru/2011/04/blog-post.html
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 21.10.2011, 01:02   #5
Lime
Форумчанин
 
Аватар для Lime
 
Регистрация: 10.02.2009
Сообщений: 815
По умолчанию

Спасибо, статью прочитал, но это немного не то. В своих программах стараюсь действовать описанными методами давно

А псевдо код такой:
Цитата:
ПотокХ.AddMessageToLog(MSG)
Начало
Подготовка текста сообщения
КритСекция.Вход
Добавление сообщения в глобальный список/LogManager
КритСекция.Выход
Конец
P.S. Статья напомнила - нужно сделать класс с настройками
Lime вне форума Ответить с цитированием
Старый 21.10.2011, 01:17   #6
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

а нет ли смысла перенести секцию и её применение внутрь самого LogManager?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 21.10.2011, 01:25   #7
Lime
Форумчанин
 
Аватар для Lime
 
Регистрация: 10.02.2009
Сообщений: 815
По умолчанию

у меня на данном этапе выглядит так:

Код:
procedure MyWriteln(const S: string);
var
  NewStr: string;
begin
  SetLength(NewStr, Length(S));
  CharToOem(PChar(S), PChar(NewStr));
  Writeln(NewStr);
end;

procedure DConsolePrint(S:string);
begin
DConsolePrintCritSect.Enter;
{$IFDEF CONSOLE}
MyWriteln(S);
{$ENDIF}
//LogManager ещё не написан :)
DConsolePrintCritSect.Leave;
end;


procedure TPortListener.PrintSyncMessage(MSG:string);
begin
if Length(MSG) > 0 then
DConsolePrint(MSG);
end;
Переделывал классы и логику из аналогичного приложения с формами (там была немного другая задача и реализация). Сейчас с "тесто-дебагом" выглядит немного хаотично

Последний раз редактировалось Lime; 21.10.2011 в 01:28.
Lime вне форума Ответить с цитированием
Старый 21.10.2011, 01:29   #8
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

я про это и говорил, чтоб поток вызывая PrintSyncMessage, не заботился про синхронизацию.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 21.10.2011, 01:39   #9
Lime
Форумчанин
 
Аватар для Lime
 
Регистрация: 10.02.2009
Сообщений: 815
По умолчанию

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

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

Последний раз редактировалось Lime; 21.10.2011 в 01:41.
Lime вне форума Ответить с цитированием
Старый 21.10.2011, 01:40   #10
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

только потоки встающие в очередь за секцию(на вход) будут стопорится, что вполне естественно.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 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