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

Вниз

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

 
vegarulez   (2012-09-18 21:34) [0]

Доброго времени суток мастерам! обычно делал работу с ком портами, отправку данных в интернет и прочие процедуры которые замораживают приложение в отдельных потоках для псевдопарралельной работы прилоджения. Делал как и описано в примерах через TThread определяя его обычно в отдельном Unit чтобы не засорять приложение - и проводил потом синхронизацию полученных потоком данных с основным приложением с помощью Synchronize,  либо используя property определённое в основновном потоке. Потребовалось сделать работу приложения с именованными каалами. скачал примеры начал разбираться, (писал уже как то тему про это - большое спасибо Сергей М. - помог разобраться) - вроде на основе примеров сделал всё что надо, но не пойму, как мне синхронизовать работу потока, который читает с именованного канала данные с основным потоком. В том примере, с которого копипастил и разбирался - сделано не так как я обычно делаю через TThread в отдельном юните - а сделано в основном коде создание потока и работа с ним. И когда в код пытаюсь вставить метод Synchronize для того чтобы добавить результаты работы потока - считанные из канала данные в TMemo или другие контролы и\или переменные основного потока - компилятор ругается. Прошу подсказать как правильно сделать работу с потоком который создаётся с помощью

// Создать поток чтения из канала.
    if BeginThread  (nil, 0, @ReadPipe, @hPipe, 0, Dummy)=0 then
        ;



и описан в основном же потоке как

procedure ReadPipe (hPipe: PHANDLE);
var
 inBuf: array[0..IN_BUF_SIZE] of AnsiChar;
 bytesRead: DWORD;
 rc: Boolean;
 lastError: DWORD;
 hEventRd: THANDLE;
 OverLapRd: OVERLAPPED;
 bytesTrans: DWORD;
 s,s_err:ansistring;
 i:integer;
begin

...
// тут работает поток на чтение из канала

     //записываю в property результат работы потока
     Formmain.Ftc_xml_ans:=s;
     //Formmain.Memo2.Lines.Add(s); // тут раньше писал напрямую в контрол - что ни есть гуд
     
     // ввёл процедуру которая делает по сути тоже что написано строчкой выше помещая из property в мемо - т.е. ни есть гуд - по идее вот тут бы надо сделать Synchronize (Formmain.tcadr_memo)
     Formmain.tcadr_memo;
     s:="";

 // Если соединение с каналом разорвано, завершить программу
 PostMessageW (hWndClient, WM_GO_AWAY, 0,0);
 ExitThread(0);
end;


Когда ReadPipe отрабатывает в локальных переменных у меня содержатся результаты чтения из именованного канала - сообственно вопрос в том - как их корректно записать в контролы - т.е. выполнить правильныую синхронизацию с основным потоком.
Завёл в основном потоке property под эти данные  - запихиваю их туда? в конце работы  а не напрямую в контролы. Сделал процедуру - которая запускается перед убийством потока ReadPipe и которая помещает значение property в контролы - но это тоже не правильно... по идее в обычно Tthread как раз эта процедура должна делаться через Synchronize("Эта процедура")... но тут ещё раз повторюсь - вставляю Synchronize - компилтор ругается...

Вообщем нид хелп! подскажите пожалуйста как правильно сделать... а то ошибки приложения валятся из за этого постоянно (


 
vegarulez   (2012-09-18 21:38) [1]

* очепятался
Завёл в основном потоке property под эти данные  - запихиваю их туда, в конце работы, а не напрямую в контролы.


 
Сергей М. ©   (2012-09-18 22:52) [2]


> вставляю Synchronize - компилтор ругается


Наверно матерно, раз ты не привел конкретный фрагмент того что и куда ты "вставляешь" и как он при этом "ругается" ..


 
Сергей М. ©   (2012-09-18 22:56) [3]


> //Formmain.Memo2.Lines.Add(s); // тут раньше писал напрямую
> в контрол - что ни есть гуд


Вот с Mемо-то как раз таки и гуд - метод Add() приводит к SendMessage(), что есть один из гуд-способов синхронизации.


 
Сергей М. ©   (2012-09-18 23:00) [4]


> писал напрямую


Тo бишь вызов Memo.Lines.Add на самом деле не является методом, "писующим напрямую" - он посылает сообщение окну стандартного виндового мемо-контрола, основной (или неважно какой) поток в нужное ему время выгребает это сообщение и отрабатывает его вполне себе синхронно.


 
vegarulez   (2012-09-19 21:09) [5]

Так а если

Formmain.Memo2.Lines.Add(s);

используется внутри дочернего потока? получается он будет ждать пока основной поток сделает add в мемо и только потом перейдёт к исполнению следующей строки своего кода(кода доп. потока)?


 
vegarulez   (2012-09-19 21:47) [6]

И ещё вопрос...
я запускаю процедуру

Formmain.tcadr_memo;

в которой используются переменные основного потока для работы с xml, описаные в основном потоке, я в них передаю данные помещённые в property, которые получил в потоке. Далее в процедуре работаю с ними(парсю сравниваю делаю запросы в БД и т.п. вообщем работаю полностью с переменными и контролами основного потока ) и потом уже помещаю результаты этой работы в мемо основной формы. А процедуру эту вызываю из под  доп.потока, передавая в неё результат через property.
поэтому вот и хочу спросить получается что это же не совсем правильно - т.е. поток вывзывает процедуру - та работает с переменными из главного потока - а в это время доп.поток висит + передача переменых без синхронизации и вызов из под потока и работа с переменными описанными в основном потоке - короче, я так думаю, что получается вкусная и питательная каша... Или я не прав? просто при использовании отдельного юнита и tthread я делал synchronize такой процедуры и вроде всё работало без сбоев.


 
Сергей М. ©   (2012-09-20 16:25) [7]


> vegarulez   (19.09.12 21:09) [5]


Да, будет ждать.


> поток вывзывает процедуру - та работает с переменными из
> главного потока - а в это время доп.поток висит


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


 
vegarulez   (2012-09-20 18:49) [8]

вот-вот и я о том же и говорю... зачётная бурда получается... поэтому вопрос как... как правильно синхронизировать. почитал некоторые статьи - нашёл описание с использованием критических секций - сделал через критические секции - потестирую - посомтрю как будет себя вести.  я открываю критическую секцию перед вызовом процедуры которая работает с переменными основного потока - передаю в неё результаты работы доп потока записав его в доп потоке в property и в процедуре обращаюсь к property и закрываю критическую секцию после окончания обращания к процедуре в блоке finally разумеется... через try чтобы если процедура упадёт критическая секция была закрыта. ...

5 минут полёт нормальный... пока тестирую.


 
Сергей М. ©   (2012-09-20 22:07) [9]

Упарил ты своими property)
Я до сих пор не пойму кто у тебя там к кому и к каким-то там property обращается ..
Проиллюстрируй во фрагментах кода ..


 
vegarulez   (2012-09-21 18:55) [10]

Unit Main;
uses
...
property tc_xml_cmd:ansistring read Ftc_xml_cmd write Ftc_xml_cmd;
...
implementation
...


ну и в процедуре сделал работу через критические секции

     try
      CritSec.Enter; // открываем секцию
      Formmain.Ftc_xml_ans:=s; // помещаем в проперти данные полученные в потоке из канала
      Formmain.tcadr_memo; // процедура работы с данными из канала записанными в property
     finally
      CritSec.Leave; // закрываем
     end


 
Сергей М. ©   (2012-09-23 19:05) [11]

А основной поток у тебя, надо понимать, обращается к свойству tc_xml_cmd когда ему вздумается, ничего не зная про критическую секцию ?

Если же знает, то почему не поместить работу с крит.секцией прямо в геттер и сеттер свойства tc_xml_cmd ?



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

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

Наверх





Память: 0.49 MB
Время: 0.068 c
15-1329343946
Иксик
2012-02-16 02:12
2013.03.22
А можно ли раскрыть эту неопределенность БЕЗ правила Лопиталя?


1-1300884510
Ольга
2011-03-23 15:48
2013.03.22
Определить путь к DLL из EXE


15-1339488214
ProgRAMmer Dimonych
2012-06-12 12:03
2013.03.22
Кириллические домены и GetAddrInfoW


15-1343757442
brother
2012-07-31 21:57
2013.03.22
Диск есть, а вот его нет!


15-1329862645
Дмитрий С
2012-02-22 02:17
2013.03.22
Спам





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