![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Взаимодействие потоков. [D6, WinXP]
Gear © (2004-08-24 13:42:00)Добрый день! Подскажите пожалуйста (очень хотелось бы пример) под Windows как заставить вторичный поток созданный основным ждать какие-либо события от основного потока и при их возникновении выполнять какие-либо действия?
По конкретней, имею сервер UDP, который в основном потоке принимает пакеты помеченные своим ID. На каждый уникальный ID создаёт вторичный поток со своими параметрами и уникальным ID (сессию). Пока основной поток получает пакеты с этим ID он из передаёт вторичному, а вторичный в свою очередь выполняет какие-либо действия (зависит от того какие в UDP пакете указаны команды на выполнения, например: GET,BYE). После того, как вторичный поток от основного получит пакет с командой BYE он должен завершится (сессия завершается).
Сейчас я остановился на том, что созданный мною вторичный поток при выполнении всех своих функций просто завершается. Как быть? Как заставить его висеть и позволять основному потоку передавать ему команды?
Fay (2004-08-24 18:22:00) [1]Код (псевдокод 8)) ужасный, но наглядный.
var
dwAnyEvent : DWORD;
procedure ThreadProc(p : Pointer); stdcall;
begin
while waitforsingleobject(dwAnyEvent, 1000) = WAIT_OBJECT_0 do
SHowMessage('!');
end;
procedure button1click(
var
th, tID : DWORD;
begin
th := CreateThread(..., 0, tID);
end;
procedure button2click(
begin
PulseEvent(dwAnyEvent);
end;
initialization
dwAnyEvent := CreateEvent(...
finalization
CloseHandle(dwAnyEvent);
end;
Gear (2004-08-24 17:38:00) [2]в дополнение..команды вторичным потокам будет давать только основной поток.
Gear (2004-08-24 17:36:00) [3]>Либо с помощью событий: TEvent VCL или CreateEvent API + WaitForSingleObject
пожалуйста если возможно небольшой пример кода как это сделать? потоков будет много. Будет известен ID каждого потока.
Суслик (2004-08-24 15:07:00) [4]
> Не утверждаю обратное, но почему не рекомендуете ?
смею предположить, что потому т.к. сам поток не сможет проснуться - его надо будить. А это противоречит исходному заданию "основным ждать какие-либо события от основного потока и при их возникновении выполнять какие-либо действия"
Digitman (2004-08-24 15:06:00) [5]
> inic © (24.08.04 14:42) [6]
> Не утверждаю обратное, но почему не рекомендуете ?
ну а если, предположим, поток должен реагировать на сообщения и/или более чем одно событие, созданные разными трэдами и взводимими ими же в сигн.состояние ? выполнить Resume способен только тот тред, который "знает" ThreadId приостановленного трэда
inic (2004-08-24 14:42:00) [6]
> Gear (24.08.04 14:26) [2]
> То есть по сути вторичный поток должен бегать постоянно
> в цикле, выполняя функцию если подходит условия и приостанавливаясь
> когда это ненужно. Это правильное решение? Может у кого-нибудь
> ещё возникнут какие решения?
Он не будет бегать, он уснет.
> Digitman
> но вот использовать Suspend я бы не рекомендовал - выводить
> его из "состоянии комы" придется индивидуально
Не утверждаю обратное, но почему не рекомендуете ?
MBo (2004-08-24 14:39:00) [7]В поточной функции вторичного потока использовать одну из Wait-функций, например, WaitForMultipleObjects.
clickmaker (2004-08-24 14:36:00) [8]PostThreadMessage + GetMessage в цикле
Либо с помощью событий: TEvent VCL или CreateEvent API + WaitForSingleObject
Digitman (2004-08-24 14:35:00) [9]
> Gear (24.08.04 14:26) [2]
решений - море, и всякое при определенных условиях можно считать "правильным"
но вот использовать Suspend я бы не рекомендовал - выводить его из "состоянии комы" придется индивидуально
Gear (2004-08-24 14:26:00) [10]То есть по сути вторичный поток должен бегать постоянно в цикле, выполняя функцию если подходит условия и приостанавливаясь когда это ненужно. Это правильное решение? Может у кого-нибудь ещё возникнут какие решения?
inic (2004-08-24 14:15:00) [11]Может так ? Хотя написано небрежно
TThread2.Execute();
begin
while True do begin
if GetCommand = BYE then Exit;
// Че то еще
Suspend;
end;
end;
TThread1.Smth ();
begin
if FThread2.Suspended then FThread2.Resume;
end;