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

Вниз

Поток, организация проверки раз в секунду PostThreadMessage   Найти похожие ветки 

 
AV ©   (2012-07-31 10:52) [0]

До этого не пользовался сообщениями, через проперти пинал потоки.

Правильно понимаю линию партии?
поток
procedure TMyTH.Execute;
var Msg: TMsg;
begin
 repeat
   if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
   begin
    DT := Msg.message;
    TranslateMessage(Msg);
    DispatchMessage(Msg);
   end;
   Sleep(1000);
   if DT = MyMessage then ; //Synchronize(Update);
   DT := 0;
 until Terminated;
end;


оповещение

 T1 := TMyTH.Create(false);

 PostThreadMessage(T1.ThreadID, WM_USER, 0, 0);


 
AV ©   (2012-07-31 11:27) [1]

Что смущает

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644943%28v=vs.85%29.aspx
>> Applies to: desktop apps only

а если планируется в сервисе?


 
Сергей М. ©   (2012-07-31 11:43) [2]

Логика ожидания/выборки/диспетчеризации/обработки сообщений в теле Execute может быть произвольной в пределах полного понимания происходящего - здесь полный простор для фантазии.

Единственные замечаня:

1. слип аж на 2 сек - это ж ни в какую Красную армию не вписывается.
Бестолковая трата драгоценного времени)

 while not Terminated do
   if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
   begin
    //TranslateMessage(Msg); // это нафих не нужно если поток не занимается обработкой сообщений клавиатурного ввода
    DispatchMessage(Msg); // иногда удобней реализовать диспетчеризацию с использованием метода TObject.Dispatch()
   end
   else
     Sleep(1);

или вариант с ожиданием/выборкой сообщений в kernel-mode:

 while not Terminated and GetMessage(Msg, 0,0,0) do
    DispatchMessage(Msg); // или Dispatch(msg.Message)
// в обработчике WM_QUIT выставить Terminated = True для выхода из цикла, WM_QUIT посылать из перекрытого деструктора перед вызовом inherited Destroy

2.

T1 := TMyTH.Create(false);

while not PostThreadMessage(T1.ThreadID, WM_USER, 0, 0) do Sleep(0);
//цикл-пустышка нужен для получения гарантии того что  последующие отправляемые потоку сообщения
// не уйдут в пустоту, ибо очередь сообщений потока создается не раньше самого первого вызова им Wait/Get/PeekMessage()


 
AV ©   (2012-07-31 11:58) [3]

Понял. Спасибо!


 
Anatoly Podgoretsky ©   (2012-07-31 12:11) [4]

Использовать функции Wait с таймаутом в одну секунду


 
AV ©   (2012-07-31 12:51) [5]


> Использовать функции Wait с таймаутом в одну секунду

не пойдет
это же только пример, реальность несколько другая :)


 
Anatoly Podgoretsky ©   (2012-07-31 12:56) [6]

> AV  (31.07.2012 12:51:05)  [5]

Sleep пойдет, а WaitFor не пойдет, странно это


 
AV ©   (2012-07-31 15:37) [7]

а, в этом смысле..
да, почему.. пойдет
тока не надо, и так достаточно.
+ я так лучше понимаю :)


 
Сергей М. ©   (2012-07-31 16:21) [8]


> не надо, и так достаточно.


Да зачем же вхолостую размандаривать кванты доступного потоку драгоценного времени ?

Ведь за то время, пока поток находится в kernel-time, он в состоянии не только тупо и беспробудно спать, но и быть готовым немедленно проснуться при наступлении интересующего его события)


 
Сергей М. ©   (2012-07-31 16:23) [9]

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


 
Dennis I. Komarov ©   (2012-07-31 22:40) [10]


> положительно скажется на сквозной производительности программы)

... и не только этой программы, а и общего самочувствия ос


 
AV ©   (2012-08-01 09:28) [11]

А кого они должны ждать?
ли без разницы, просто ждать, что бы быть готовым?

 TMyTH = class(TThread)
 private     { Private declarations }
   DT: Cardinal;
   CNT: Integer;
 protected
   procedure Execute; override;
   procedure Update;
 public
   FName: string;
   FMSG: Cardinal;
   T: TMyTH;
 end;

procedure TMyTH.Execute;
var Msg: TMsg;
begin
 while not Terminated do
 begin
   if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
   begin
     DT := Msg.message;
     DispatchMessage(Msg);
   end else
     WaitForSingleObject(MainThreadID, 1); // или без разницы, просто ждать

   if DT = FMSG then
   begin
     DT := 0;
     CNT := CNT + 1;
     if T <> nil then
       PostThreadMessage(T.ThreadID, T.FMSG, 0, 0);
     Update;
   end;
 end;
end;

procedure TMyTH.Update;
begin
 try
  EnterCriticalSection(Form1.CS);
  form1.mmo1.Lines.Add( FName + " " + IntToStr(GetTickCount));
 finally
  LeaveCriticalSection(Form1.CS);
 end;
end;

----
  T1 := TMyTH.Create(true);
  T1.FName := "T1";
  T1.FMSG := WM_USER + 1;

  T2 := TMyTH.Create(true);
  T2.FName := "T2";
  T2.FMSG := WM_USER + 2;

  T1.T := T2;
  T2.T := T1;

  InitializeCriticalSection(CS);

  T1.Resume;
  T2.Resume;

  PostThreadMessage(T1.ThreadID, WM_USER + 1, 0, 0);


 
Сергей М. ©   (2012-08-01 11:49) [12]


> AV ©   (01.08.12 09:28) [11]
>
> А кого они должны ждать?


Ну в твоем случае никого/ничего кроме адресованных им сообщений они не ждут. И кроме собственно синхронной обработки этих сообщений они больше ничем не занимаются.

А раз так, то PeekMessage со слипом впридачу ничем, imho, не оправдан.

А раз не оправдан, то значит ждать и выбирать свои сообщения твоим потокам нужно переходя в kernel-time - GetMessage (или ее эквивалент WaitMessage + PeekMessage)


 
Dennis I. Komarov ©   (2012-08-01 12:20) [13]


>    WaitForSingleObject(MainThreadID, 1); // или без разницы,
>  просто ждать

WaitForSingleObject(hEvent, ...) is function

P.S. Могу наврать, Delphi нет под рукой...


 
Dennis I. Komarov ©   (2012-08-01 13:10) [14]


> это же только пример, реальность несколько другая :)

Опиши реальность, а то пока полная ерунда...

> тока не надо, и так достаточно.
> + я так лучше понимаю :)

Это тебя не оправдывает :)


 
AV ©   (2012-08-01 13:24) [15]


> WaitForSingleObject(hEvent

да, так
и он должен сигналить


>  кроме собственно синхронной обработки этих сообщений они
> больше ничем не занимаются.

сейчас так, они просто друг друга пинают :)
Я к чему подвожу все это безобразие..

потом потоки(, окна, етц. )
будут ждать только сообщение.
В W|L параметрах куда положить результат.
Посчитали, положили по адресу, ответили .

Один диспетчер, который принимает все сообщения от всех и раздает их всем остальным. Кому нужна реакция тот пусть реагирует.

т.е. кто-то захотел посчитать то, что умеет Т1. Он пуляет сообщение диспетчеру. Диспетчер всем раздает. Т1 узнает себя и начинает работать, остальные игнорируют, т.к. сообщение им не известно.
Некоторые заинтересовались, т.к. им известно что это такое.

Т1 посчитал, ответил диспетчеру. Диспетчер всем раздал.
Кто просил получил
И кто заинтересовался до этого, тоже получил.
Кто опять не понял - опять проигнорировал.

итого, все обязаны знать только диспетчера.
и логика работы у всех одинаковая


 
Leonid Troyanovsky ©   (2012-08-01 16:31) [16]


> AV ©   (01.08.12 13:24) [15]

http://rsdn.ru/forum/delphi/883505.1.aspx

--
Regards, LVT.


 
Dennis I. Komarov ©   (2012-08-01 19:45) [17]


> > WaitForSingleObject(hEvent
>
> да, так
> и он должен сигналить

А ты ему что скормил? Отваливает он по time-out и ничего более, так где смысла?


 
AV ©   (2012-08-02 11:20) [18]

Вот и думаю, где. Поток по идее не знает, кого ему ждать.
а скормил что-то, первое попавшееся, пусть по таймату и отваливает. Но тогда и слип пойдет, в принципе..


> Leonid Troyanovsky ©   (01.08.12 16:31) [16]

гуглем находил :)

Непонятно уже самуму что хочу.
Надо задаяу поставить себе четче..
Тогда я пока почитать и сформулировать


 
Dennis I. Komarov ©   (2012-08-02 18:39) [19]


> Вот и думаю, где. Поток по идее не знает, кого ему ждать.
>
> а скормил что-то, первое попавшееся, пусть по таймату и
> отваливает. Но тогда и слип пойдет, в принципе..
>

А ждать он должен наступления события и не секунду, а пока не наступит (иу или...)
наступило - поехали, нет - сидит поток тихо и не вякает... и всем хорошо :)



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

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

Наверх




Память: 0.5 MB
Время: 0.06 c
15-1351694777
Handler
2012-10-31 18:46
2013.03.22
как будет на английском


15-1343674849
alexdn
2012-07-30 23:00
2013.03.22
php


15-1336905711
Contaka
2012-05-13 14:41
2013.03.22
про контакт


15-1352816598
mfender
2012-11-13 18:23
2013.03.22
Fatal error. Не создаётся .dcu


3-1284544747
yurikon
2010-09-15 13:59
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
Английский Французский Немецкий Итальянский Португальский Русский Испанский