Форум: "Основная";
Текущий архив: 2006.03.05;
Скачать: [xml.tar.bz2];
ВнизЕсть ли в моей программе несколько одновременных потоков? Найти похожие ветки
← →
passer © (2006-01-30 15:33) [0]Есть у меня программка (звонилка самодельная).
В ней основная процедура соединения делает следующее
procedure DialClick;
begin
// всяко разно
while Automat(...) do
begin
Sleep(100);
Application.ProcessMessages;
end;
// всяко разно
end;
А вот в процедуре Automat вызывается виндовый RasDial с callback функцией RasDialCallback, в которой в свою очередь запускаетя мультимедийный таймер timeSetEvent со своей callback функцией. И все эти функции (Automat, RasDialCallback, TimerCallback) пользуются одним экземпляром опеределенного класса (TMainDial), читают определенные поля, пишут в лог, читают этот лог и изменяют компоненты на форме.
Насколько я понял, обе эти callback функции вызываются асинхронно относительно основной (Autоmat). Насчет таймерной, в принципе, уверен точно. Явно написано, что не привязано к обработке очереди сообщений.
Так проблема в том, что похоже они все одновременно могут выполнять взаимоисключающие действия над экземпляром TMainDial и иногда происходит AcsessViolation (извиняюсь за ангийскую орфографию), который я никак не могу поймать.
Так вот в чем вопрос.
Это все похоже на одновременную работу нескольких потоков безо всяких TThread. Но самому никогда не приходилось программировать в несколько потоков. И каким образом развести мне эти операции без этого самого Thread? Там, насколько я есть какая-то Sinhronize.
Но что делать в такой ситуации мне? Как синхронизировать обращения к полям класса, чтоб убрать AcsessViolation?
Или я ошибаюсь в месте определения ошибки - и никаких потоков нет, и синхронизации здесь в принципе не нужно?
← →
Digitman © (2006-01-30 15:37) [1]Automat(...) - ТВОЯ функция ?
← →
Набережных С. © (2006-01-30 17:54) [2]
> Насколько я понял, обе эти callback функции вызываются асинхронно
> относительно основной (Autоmat). Насчет таймерной, в принципе,
> уверен точно
И как ты себе представляешь такое поведение без дополнительных потоков?
← →
passer © (2006-01-30 19:16) [3]для Digitman
> Automat(...) - ТВОЯ функция ?
Да моя.
для Набережных
> И как ты себе представляешь такое поведение без дополнительных
> потоков?
Так может их виндовс создает. По таймерной точно сказано, что не провязано к обработке сообщений. Если б я использовал стандартный VCL таймер, то OnTimer обрабатывался бы в основном потоке, когда я ему разрешал это по Application.ProcessMessages. А с мультимедийным похоже по другому.
← →
Leonid Troyanovsky © (2006-01-30 19:26) [4]
> passer © (30.01.06 15:33)
View - Debug Windows - Threads.
--
Regards, LVT.
← →
Набережных С. © (2006-01-30 20:16) [5]
> passer © (30.01.06 19:16) [3]
> Так может их виндовс создает.
Разумеется соэдает. Но от этого они не перестают быть частью именно твоего процесса.
Так что на вопрос, сформулированный в заголоаке, ответ - безусловно "да".
> Но самому никогда не приходилось программировать
> в несколько потоков. И каким образом развести мне эти операции
> без этого самого Thread? Там, насколько я есть какая-то
> Sinhronize.
С помощью использования критической секции при обращении к тем данным, к которым обращаются твои каллбэки. Причем крит. секция должна использоваться при обращении к этим данным и из главного потока.
← →
Digitman © (2006-01-31 08:44) [6]
> passer © (30.01.06 19:16) [3]
> Да моя.
Ну а коли твоя, то тебе ли не знать что у тебя в этой ф-ции творится в части доп.потоков ..
← →
evvcom © (2006-01-31 10:38) [7]Поставь бряки на калбеках и посмотри в каких потоках они выполняются (см. [4]). Хотя все это должно быть описано в документации. Если в разных потоках, то синхронизируй (см. [5])
← →
kaZaNoVa © (2006-01-31 11:19) [8]
Var cs:_RTL_CRITICAL_SECTION;
procedure TForm1.FormCreate(Sender: TObject);
begin
InitializeCriticalSection(cs); //инициализируем (на старте программы, 1 раз)
end;
EnterCriticalSection(cs);
//тут обращаемся к полям ...
LeaveCriticalSection(cs);
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
DeleteCriticalSection(cs); //удаляем
end;
← →
evvcom © (2006-01-31 11:29) [9]
> Var cs:_RTL_CRITICAL_SECTION;
если это глобальная переменная, то и инитить и делетить ее нужно глобально, и соответственно защищать она должна глобальные данные. Если же защищать нужно какие-то данные класса, то соответственно и объявлять ее надо как поле класса.
← →
Leonid Troyanovsky © (2006-01-31 11:59) [10]
> passer © (30.01.06 15:33)
> Но что делать в такой ситуации мне? Как синхронизировать
> обращения к полям класса
Если это действительно callback function by the timeSetEvent,
то никакой "синхронизации" не получится, бо из нее нельзя
вызывать ничего кроме PostMessage, timeGetSystemTime,
timeGetTime, timeSetEvent, timeKillEvent, midiOutShortMsg,
midiOutLongMsg, and OutputDebugString.
Т.е., кинуть в лог, конечно, можно (например, PostMessage),
а вот прочитать чего - сомнительно.
--
Regards, LVT.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.03.05;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.01 c