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

Вниз

Сообщение в нить, созданной 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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.028 c
3-1148137898
wirg
2006-05-20 19:11
2006.07.23
Подскажите как исправить название в заголовке Грида


5-1135664859
DimaBr
2005-12-27 09:27
2006.07.23
Похожие компоненты


2-1141049034
Arazel
2006-02-27 17:03
2006.07.23
Закрыть порты TCP:135/UDP:445 програмным образом


1-1149781802
pound
2006-06-08 19:50
2006.07.23
Как копировать в буфер обмена из Edit


15-1151040139
Ega23
2006-06-23 09:22
2006.07.23
С Днём рождения! 23 июня