Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Вниз

Синхронизация и гонки потоков   Найти похожие ветки 

 
megavoid (other pc)   (2012-07-29 11:02) [0]

Доброго выходного дня, уважаемые мастера! Я в очередной раз перемудрил сам себя.

Имеется приложение-многозвенка, ехе запускается у клиента и гоняет трафик между удалённым сервером и внешней сторонней железкой. Сетевая часть с самого начала была задумана в потоке. Пока чтение данных с железки было функцией в главном потоке, всё было хорошо. Проблемы начались при выносе цикла чтения в отдельный поток.

Архитектура потока такова:
procedure ReaderThread.Execute;
begin
while not Termiated do begin
 res := ReadDataFromHardware;
 if not (res) continue
 else begin
 Synchronize(procedure begin  // race!!!
   SyncRecord.Fields := SetThemFromHardwareData;
 end);
 SetEvent(E1);
 end;
end;
end;


главный поток:
procedure HardwareSession;
begin
Reader := ReaderThread.Create(True, DataForThread);
Reader.Resume;
SendDataToHardware(BeginDataExchange);
repeat
res := WaitForMultipleObjects(Objects,1);
case
WAIT_SIGNALED_E1: Actions;
WAIT_SIGNALED_OTHERS: SendDifferentDataToHardware or SetStopFlag;
dec(timeout);
// тут было ReadDataFromHardware (без потока)
until StopFlag or Timeout=0;
end;


Судя по отладочной печати: ReaderThread запускается, получает данные, но его Synchronize выполняется только после того, как repeat завершается по таймауту, когда уже поздно.

Если же в главном потоке перед последней строчкой until StopFlag or Timeout вкорячить ProcessMessages, то получаю главенство уже читающего потока (readfromhardware довольно шустрая), в лог записывается, что поток читалки не отдаёт управление главному, пока не получит всю очередь данных от железки (пока ей даёт ProcessMessages?), и уже только после этого repeat входит на следующую итерацию,  видит событие Е1 (а его уже на самом деле 100 раз подняли), хочет выполнить Action, но теперь тоже уже поздно, железка не дождалась ответа и ушла по таймауту, о чём поток читалки грустно и сообщает уже другим событием на следующей итерации ProcessMessages.

Выше я упоминал про сетевой поток. Его синхронизация организована точно так же, как и в ReaderThread - Synchronize(proc begin SyncRecord.SetFields end); затем установка соответствующего Eventа. Получает он данные так же - waitformultiple(Events), по событию через Synchronize забирает данные и занимается далее своей сетевой работой. Всё синхронизировалось нормально (отладочные сообщения выводятся в нужной последовательности).

Парадокс - с сетевым потоком нормально, а с ещё одним ненормально??? Подозреваю, что это называется, скорее, не парадокс, а криворукость. Перечитал статью GunSmokera, перечитал Рихтера, справку, понимаю, что попал на классические гонки, но всё равно туплю. Уважаемые мастера, подскажите, пожалуйста, куда копать?


 
Cobalt ©   (2012-07-29 13:13) [1]

Для начала определись, как ты хочешь чтобы потоки работали, а потом реализуй это.
И, раз уж ты пользуешься методом Synchronize, узнай как он работает.


 
megavoid ©   (2012-07-30 09:22) [2]

Cobalt, покопался, Synchronize создаёт событие, входит в критическую секцию, выполняет переданную подпрограмму, выходит из секции.
Я и говорю, перемудрил я сам себя с архитектурой (( печально переписываю



Страницы: 1 вся ветка

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

Наверх





Память: 0.46 MB
Время: 0.083 c
15-1332688326
Дмитрий С
2012-03-25 19:12
2013.03.22
Физически 32х битная система может иметь доступ к


15-1340886646
alexdn
2012-06-28 16:30
2013.03.22
10-ти дневн демка


2-1328619572
Сергей
2012-02-07 16:59
2013.03.22
Как подключиться к Oracle?


2-1339496022
Разведка
2012-06-12 14:13
2013.03.22
Как приравнять тип из Си к типу Delphi?


15-1337023240
Kerk
2012-05-14 23:20
2013.03.22
Ищется компонент/модуль для шифрования/дешифрования AES-256





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский