Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

Поток, организация проверки раз в секунду 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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.059 c
2-1330073361
NieL
2012-02-24 12:49
2013.03.22
проверка перед добавлением


1-1304237779
AlekVolsk
2011-05-01 12:16
2013.03.22
Экспорт в Excel2010: значения NumberFormat ячейки


15-1341124080
Mihaker
2012-07-01 10:28
2013.03.22
Win7 ShellServiceObjectDelayLoad


15-1347000404
ford
2012-09-07 10:46
2013.03.22
алгоритм для анализа изображения


15-1337097562
brother
2012-05-15 19:59
2013.03.22
Интересно мнение: