![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сообщение в нить, созданной CreateThread
learner © (2006-06-24 06:47:00)Здравствуйте !
Я использую CreateThread для создания нити.
Как мне ей сообщить что ей надо закругляться,
и подождать пока она "закруглиться".
Leonid Troyanovsky (2006-07-04 18:43:00) [1]
> learner © (04.07.06 15:43) [9]
> Как сделать, чтобы сообщение, посланное в нить при помощи
> PostThreadMessage
> "не терялось" ?
Для этого надо, чтобы к этому моменту у потока уже существовали
очереди сообщений, т.е., чтобы поток-адресат успел вызвать
к-л функцию user32 or gdi32.
И, конечно, не стоит забывать про описанное в [10].
--
Regards, LVT.
Ketmar (2006-07-04 16:38:00) [2]а куда это оно "теряется"? вы забирать сообщения из очереди не пробовали? с учётом того, что очередь -- она далеко не безразмерна, забирать желательно почаще.
learner (2006-07-04 15:43:00) [3]Еще вопрос появился.
Как сделать, чтобы сообщение, посланное в нить при помощи PostThreadMessage
"не терялось" ?
learner (2006-06-25 14:31:00) [4]Спасибо огромное: все получилось.
Отдельное спасибо Leonid Troyanovsky.
Leonid Troyanovsky (2006-06-25 10:21:00) [5]
> learner © (25.06.06 05:38) [6]
> У меня поток в цикле ожидает OVERLAPPED.hEvent
> В OVERLAPPED это событие единственное. Как потоку отличить
> Event - "правильный", или это команда на выход из цикла
Ожидание в этом случае должно быть в функции WaitForMultipleObjects
(with fWaitAll = False), сработавшее событие определяется возвращаемым
ею результатом ( - WAIT_OBJECT_0).
--
Regards, LVT.
learner (2006-06-25 05:38:00) [6]> [1] Leonid Troyanovsky © (24.06.06 14:59)
> Или, в случае, когда поток занят, в основном, ожиданием
> объектов синхронизации в функциях WaitForXXX можно добавить
> к ожидаемым
> объектам событие (Event cо сбросом вручную), по срабатыванию
> которого поток(и) завершит свою функцию.
У меня поток в цикле ожидает OVERLAPPED.hEvent
В OVERLAPPED это событие единственное. Как потоку отличить
Event - "правильный", или это команда на выход из цикла ?
Пусик (2006-06-24 17:59:00) [7]> Все это лишнее, бо GetMessage знает, что такое WM_QUIT.
Это пример.
А за комментарий спасибо.
Leonid Troyanovsky (2006-06-24 17:38:00) [8]
> Пусик © (24.06.06 15:48) [3]
> PeekMessage(Msg,0,0,0,pm_NoRemove);
Это-то зачем?
> case MSg.message of
> UM_Exit:
> begin
> Sleep(2000);
> ExitThread(0);
> end;
Все это лишнее, бо GetMessage знает, что такое WM_QUIT.
--
Regards, LVT.
Пусик (2006-06-24 15:48:00) [9]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
const
UM_Exit = WM_USER+1;
UM_ShowMsg = WM_USER+2;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
end;
var
Form1: TForm1;
ThreadId: THandle;
HThread: THandle;
implementation
{$R *.dfm}
procedure ThreadProc(p: Cardinal);
var
Msg: TMsg;
begin
PeekMessage(Msg,0,0,0,pm_NoRemove);
while GetMessage(Msg,0,0,0) do
begin
case MSg.message of
UM_Exit:
begin
Sleep(2000);
ExitThread(0);
end;
UM_ShowMsg: MessageBox(0,'Message!','Message',MB_OK);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
HThread := BeginThread(nil,0,@ThreadProc,nil,0,ThreadId);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
PostThreadMessage(ThreadId,UM_ShowMsg,0,0);
end;
procedure TForm1.Button3Click(Sender: TObject);
var
Code: DWORD;
begin
PostThreadMessage(ThreadId,UM_Exit,0,0);
WaitForSingleObject(HThread,INFINITE);
GetExitCodeThread(HThread,Code);
MessageBox(0,PChar('Thread end. ExitCode='+IntToStr(Code)),'Message',MB_OK);
CloseHandle(HThread);
end;
end.
isasa (2006-06-24 15:22:00) [10]HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter, //<- Вот здесь передать адрес структуры в которой одно из полей, флаг завершения потока
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
Во время выполнения потока флаг проверять и реагировать по его значению
в качестве структуры
^record
goThread: integer;
...
end;
Leonid Troyanovsky (2006-06-24 14:59:00) [11]
> learner © (24.06.06 06:47)
> Я использую CreateThread для создания нити.
А чего же, собс-но, не TThread?
Или, на худой конец, BeginThread.
> Как мне ей сообщить что ей надо закругляться,
Зависит от того, что делает созданный поток.
Например, он делает какие-то длительные вычисления,
которые необходимо прервать на каком-то этапе.
Тогда, на каждом этапе он должен делать проверку,
скажем, InterLockedExchangeAdd(@Terminated, 0) <> 0,
где Terminated: Longint - признак завершения.
Ну, а для установки признака сгодится
InterLockedExchangeAdd(@Terminated, 1).
Или, в случае, когда поток занят, в основном, ожиданием объектов синхронизации в функциях WaitForXXX можно добавить к ожидаемым
объектам событие (Event cо сбросом вручную), по срабатыванию
которого поток(и) завершит свою функцию.
> и подождать пока она "закруглиться".
WaitForSingleObject(hThread, INFINITE)
--
Regards, LVT.