Форум: "Начинающим";
Текущий архив: 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.062 c