关于线程结束的问题,接着刚才的,(25分)

  • 主题发起人 主题发起人 netfire_fly
  • 开始时间 开始时间
N

netfire_fly

Unregistered / Unconfirmed
GUEST, unregistred user!
主线程结束我用
MainThread.Terminate;
//等待线程退出
while WaitForSingleObject(MainThread.Handle, 0) <> WAIT_OBJECT_0do
for J := 0 to 1000do
Application.ProcessMessages;
在主线程中的次级线程结束方法
while not Terminateddo
begin
...
if Terminated then
Break;
...
end;
可是当我要结束线程的时候,用单步运行查看:MainThread.Terminated=true,但是次级线程SecondThread.Terminate
却等于false,还是无法结束,线程结束时,线程到底是怎么做的.我该如何写代码呢.
还有个问题就是创建线程时,有时候句柄为0,这以为着线程为无效?但是线程却可以运行啊,这又是
这么回事.不好意思,分少了点.
拜托了,各位
 
同志们帮忙啊
 
我重新写了一个,帮我看看,谢了哈
MainThread.Terminate;
//等待线程退出
while WaitForSingleObject(MainThread.Handle, 0) <> WAIT_OBJECT_0do
begin
if (now-Runtime)>0.0001 then
begin
TerminateThread(MainThread.Handle,Return);//执行这里出错,为什么,我实在没有办法停止了
break;
end;
for J := 0 to 10do
Application.ProcessMessages;
end;
 
MainThread 不是给你free了吧
 
WINDOWS同一进程中线程没有主次之分,只是我们的程序中有主线程和副线程之说。
所有线程是平等的,但各线程可以设置优先级。
因此,你的所谓“主线程”Terminate甚至FREE的时候,并不会导致“次级线程”也
退出。
事实上,我看你的代码,“主线程”在创建完“次级线程”后就立即退出了,只剩下
次级线程在运行。你只需要一个一个地将“次级线程”结束就行了。
 
Delphi入门与精通中提了次级线程的说法啊,
那么我想问,如果我想在上一级的线程结束的时候,同时让它创建的地线程也结束,那怎么做呢
 
创建次级线程时,用一个线程数组把它们记录下来,然后写一个过程把它们全结束掉。
在主线程EXECUTE的最后(或FREE时)调用这个过程。
unit Unit3;
interface
uses
Classes;
type
TMultiSearchThread = class(TThread)
private
{ Private declarations }
SearchThreads: array of TThread;
protected
procedure Execute;
override;
procedure StopAllThreads;
end;

const
SEARCHTHREAD_COUNT = 1;
implementation
uses Unit2, Unit1;
{ TMultiSearchThread }
procedure TMultiSearchThread.Execute;
var
multithread: TMainSearchThread;
//需要调用次级线程
i: integer;
begin
//Form1.PFilelist.Cursor := crHourGlass;
SetLength(SearchThreads, SEARCHTHREAD_COUNT);
for i := 0 to SEARCHTHREAD_COUNT - 1do
begin
MultiThread := TmainSearchThread.Create(true);
SearchThreads := MultiThread;
MultiThread.FreeOnTerminate := true;
MultiThread.Resume;
if Terminated then
exit;
//Form1.pFileList.cursor := CrDefault;
end;

//Suspend;
//挂起
//StopAllThreads;//一旦激活,则立即结束
end;

procedure TMultiSearchThread.StopAllThreads;
var
multithread: TThread;
i: integer;
begin
for i := 0 to SEARCHTHREAD_COUNT - 1do
begin
MultiThread := SearchThreads;
MultiThread.Terminate;
//通知停止
end;
for i := 0 to SEARCHTHREAD_COUNT - 1do
begin
MultiThread := SearchThreads;
MultiThread.WaitFor;
//等待
end;
end;
但这样你会发现你的主线程的问题:创建完次线程后,主线程没事做了,就会结束。
因此,你的主线程应该要在创建次线程完成后就挂起。要停止时先将其激活。
 
> Delphi入门与精通中提了次级线程的说法啊,
> 那么我想问,如果我想在上一级的线程结束的时候,同时让它创建的地线程也结束,那怎么做呢
所有线程用数组纪录自己创建的线程,
如果父线程正常退出,他可以通知子线程退出,各个子线程正常退出,他们可以通知各自的子线程也退出,……
但是如果是非正常终止,那么子线程是继续运行的
 
除非创建子线程的时候把自己的线程号传给子线程,子线程经常检查父线程是否还在运行,发现
父线程停止了,那么自己也自杀
 
我今天晚上试了一下,对于一个单一的线程,要终止,只要用
TMainThread.suspend;
TMainThread.Terminate;
TMainThread.free;
这样的代码就可以了,

 
我按照两位说的.写了如下的东西,改了一个例子
unit Umulti;
interface
uses
Windows, Messages,UfindThread, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,ComCtrls;
type
TMultiFind = class(TThread)
private
SearchThreads: Array of TThread ;
{ Private declarations }
protected
Progr:integer;
Finders:Array[1..4]of TFindThread;
Procedure UpdateProgress;
Procedure show;
procedure Execute;
override;
Procedure StopAllThreads;
Public
LookFor,OutPut:string;
Progress:array[1..5]of TProgressBar;
end;
const
SearchThread_Count=4;
implementation
uses Uform;
{ Important: Methods and properties of objects in VCL or CLX can only be used
in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure TMultiFind.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
{ TMultiFind }
Procedure TMultiFind.UpdateProgress ;
begin
Application.ProcessMessages;
Progress[1].Position :=Progr;
end;

procedure TMultiFind.show;
begin
ShowMessage(Output);
end;

Procedure TMultifind.StopAllThreads ;
var
MultiThread:TThread;
i:integer;
begin
for i:=1 to SearchThread_countdo
begin
MultiThread:=Finders;
MultiThread.Terminate;
end;
for i:=1 to 4do
begin
MultiThread:=Finders;
MultiThread.waitfor;
end;
end;

procedure TMultiFind.Execute;
var
//Finders:Array[1..4]of TFindThread;
MultiThread:TThread;
i,j:integer;
begin
Setlength(SearchThreads,SearchThread_count);
for I:=1 to SearchThread_countdo
begin
if Terminated then
exit;
Finders:=TFindThread.Create(true);
Finders.LookFor:=LookFor;
Finders.Progress :=Progress[I+1];

Finders.FreeOnTerminate:=true;
Finders.Resume;
end;
//wait the Threads to end.
..
for j:=1 to 4do
begin
{ if Terminated then
//如果不用suspend,就这样用括号种的代码

begin
for i:=1 to SearchThread_countdo
begin
MultiThread:=Finders;
MultiThread.Terminate;
end;
for i:=1 to 4do
begin
MultiThread:=Finders;
MultiThread.waitfor;
end;
exit;
end;
}
//---------------------------------
Finders[j].WaitFor;
//如果有这句,父线程要等它的子线程运行结束才能运行下面的语句
Progr:=j;
synchronize(UpdateProgress);
end;
suspend;
//好像没有起作用是不是我写错了
stopallThreads;
//show the Result
Output:='Found:';
for I:=1 to 4do
Output:=output+Format('%s NO is %d,',
[LookFor,Finders.Found]);
Synchronize(show);

end;

end.
//---------------------------终止线程的调用--------------
procedure TForm1.Button3Click(Sender: TObject);
var i:integer;
begin
{MainThread.Suspend ;
MainThread.Terminate ;
While WaitforSingleObject(MainThread.Handle,0)<>WAIT_OBJECT_0do
for i:=0 to 10do
Application.ProcessMessages ;
MainThread.Free;
} //如果用括号种的代码时,可以让所有的子线程停止,但是无法终止
//MainThread.Free这句无法执行,一直在处理Messages
MainThread.Resume;
end;

谁要源码,帮我调试一下,感激不尽
 

对于工作线程使用,我建议用消息机制.
线程退出只需捕获WM_QUIT消息即可。
实现代码如下
{ TMythread }
constructor TMythread.create;
begin
inherited create(false);
priority:=tplower;
while (PostThreadMessage(ThreadID, WM_MY_BASE, 0, 0)=false)do
begin
Sleep(100);
end;
end;

destructor TMythread.Destroy;
begin
PostThreadMessage(ThreadID, WM_QUIT, 0, 0);
WaitForSingleObject(Handle, INFINITE);
inherited;
end;

procedure TMythread.Execute;
var
hkmsg:MSG;
msgchno:integer;
begin
while (GetMessage(hkmsg, 0, 0, 0)=true)do
begin
if hkmsg.message=WM_MY_BASE then
begin
continue;
end else
begin
//Process code
end;
end;
end;
 
能解释一下吗,看得不是很懂,WM_MY_BASE是自己定义的消息么?
 
只能学习了!
 
后退
顶部