Форум: "Начинающим";
Текущий архив: 2006.07.23;
Скачать: [xml.tar.bz2];
Вниз
Сообщение в нить, созданной CreateThread Найти похожие ветки
← →
learner © (2006-06-24 06:47) [0]Здравствуйте !
Я использую CreateThread для создания нити.
Как мне ей сообщить что ей надо закругляться,
и подождать пока она "закруглиться".
← →
Leonid Troyanovsky © (2006-06-24 14:59) [1]
> 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.
← →
isasa © (2006-06-24 15:22) [2]HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter, //<- Вот здесь передать адрес структуры в которой одно из полей, флаг завершения потока
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
Во время выполнения потока флаг проверять и реагировать по его значению
в качестве структуры
^record
goThread: integer;
...
end;
← →
Пусик © (2006-06-24 15:48) [3]
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.
← →
Leonid Troyanovsky © (2006-06-24 17:38) [4]
> Пусик © (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 17:59) [5]> Все это лишнее, бо GetMessage знает, что такое WM_QUIT.
Это пример.
А за комментарий спасибо.
← →
learner © (2006-06-25 05:38) [6]> [1] Leonid Troyanovsky © (24.06.06 14:59)
> Или, в случае, когда поток занят, в основном, ожиданием
> объектов синхронизации в функциях WaitForXXX можно добавить
> к ожидаемым
> объектам событие (Event cо сбросом вручную), по срабатыванию
> которого поток(и) завершит свою функцию.
У меня поток в цикле ожидает OVERLAPPED.hEvent
В OVERLAPPED это событие единственное. Как потоку отличить
Event - "правильный", или это команда на выход из цикла ?
← →
Leonid Troyanovsky © (2006-06-25 10:21) [7]
> learner © (25.06.06 05:38) [6]
> У меня поток в цикле ожидает OVERLAPPED.hEvent
> В OVERLAPPED это событие единственное. Как потоку отличить
> Event - "правильный", или это команда на выход из цикла
Ожидание в этом случае должно быть в функции WaitForMultipleObjects
(with fWaitAll = False), сработавшее событие определяется возвращаемым
ею результатом ( - WAIT_OBJECT_0).
--
Regards, LVT.
← →
learner © (2006-06-25 14:31) [8]Спасибо огромное: все получилось.
Отдельное спасибо Leonid Troyanovsky.
← →
learner © (2006-07-04 15:43) [9]Еще вопрос появился.
Как сделать, чтобы сообщение, посланное в нить при помощи PostThreadMessage
"не терялось" ?
← →
Ketmar © (2006-07-04 16:38) [10]а куда это оно "теряется"? вы забирать сообщения из очереди не пробовали? с учётом того, что очередь -- она далеко не безразмерна, забирать желательно почаще.
← →
Leonid Troyanovsky © (2006-07-04 18:43) [11]
> learner © (04.07.06 15:43) [9]
> Как сделать, чтобы сообщение, посланное в нить при помощи
> PostThreadMessage
> "не терялось" ?
Для этого надо, чтобы к этому моменту у потока уже существовали
очереди сообщений, т.е., чтобы поток-адресат успел вызвать
к-л функцию user32 or gdi32.
И, конечно, не стоит забывать про описанное в [10].
--
Regards, LVT.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.07.23;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.014 c