主线程在创建若干子线程的地方(并启动), 需要等待子线程的执行结果例程如下:
应该怎么写,让主线程suspend 等待所有子线程terminate? 由于设置了FreeOnTerminate = true,也可以是等待所有子线程Free掉; 我的写法是 在启动子线程和取用返回值之间插入:
repeat
CanContinue := True;
for i := 0 to Count - 1 do
CanContinue := CanContinue and (Self.Fthrds[i] = nil); // Threads have set FreeOnTerminate True
until CanContinue;不过,效果不是我所需要的,主线程是Stall了(好像是死循环了 :(),子线程也都走不完了...
应该怎么写,让主线程suspend 等待所有子线程terminate? 由于设置了FreeOnTerminate = true,也可以是等待所有子线程Free掉; 我的写法是 在启动子线程和取用返回值之间插入:
repeat
CanContinue := True;
for i := 0 to Count - 1 do
CanContinue := CanContinue and (Self.Fthrds[i] = nil); // Threads have set FreeOnTerminate True
until CanContinue;不过,效果不是我所需要的,主线程是Stall了(好像是死循环了 :(),子线程也都走不完了...
Self.Fthrds[i].waitfor但是你首先要保证你所有的子线程能够正常结束
Self.Fthrds[i].waitfor这句算什么?
thrdarr: array [0..子线程数-1] of Integer;
i: Integer;
begin
// 先启动所有子线程 for i := 0 to 子线程数-1 do
thrdarr[i] := 子线程[i].handle;
waitformultipleobjects(子线程数, @thrdarr, true, INFINITE);
end;
MyId: Integer;
OnFinished: TOnThreadFinishedEvent;
protected:
procedure Execute; override;
end;procedure TMyThread.Execute;
var
Rst: Integer;
begin
...
if Assigned(OnFinished) then
OnFinished(MyId, Rst);
end;
主线程声明一个函数
procedure DoThreadFinished(ThreadId: Integer; Rst: Integer);
begin
...
end;在创建子线程时,把DoThreadFinished赋给子线程的OnFinished(最好做成属性),并且给子线程的MyId赋一个唯一的值(这样可以在DoThreadFinished知道是哪个线程执行结束了)
CanContinue := True;
for i := 0 to Count - 1 do
CanContinue := CanContinue and (Self.Fthrds[i] = nil);
until CanContinue;
死循环是因为Self.Fthrds[i] = nil这句永远不可能为True,因为子线程执行完自动释放之后并不会去设置你主线程的Self.Fthrds[i]为nil
应该是子线程执行后,发个消息给主线程,这样比较合理,如你开始所设计,主线程在等,就失去了多线程的意义了正常,我做的,是用个信号量来通知,
看看 WaitforSingleObject, WaitForMultipleObjects
thank you all
不过,我没有实践成功...最后我还是弄个TTime 设置500ms间隔 主动查询那n个子线程是否 都 已经终止(并Free掉了)。
>> 死循环是因为Self.Fthrds[i] = nil这句永远不可能为True,因为子线程执行完自动释放之后并不会去设置你主线程的Self.Fthrds[i]为nil你说得没错,子线程实例Free掉,外部的引用不会同时置为nil;
但是,子线程似乎一直处于Wait状态了,可能是主线程的优先级比我创建的子线程优先级高(默认)
所以,都到不了执行后终止的过程。
设一个全局变量
var
ThreadCount: integer;
主线程中加入 while ThreadCount := 0 do sleep(20); //等待子线程的总数不等于0时等待20ms;在子线程的Execute中ThreadCount := ThreadCount + 1;
在子线程的Destroy中ThreadCount := ThreadCount - 1;
这样是否是您所要的功能?
ThreadCount: integer;
这个是子线程的总数