在我的一个线程中,我创建了几个子线程,然后我想在子线程都完成的情况下执行一些操作我下面的代码行吗?如果不行,请帮我指出来,最好给我一个类似的例子,
var
   FEvent arrat[0..5]  :Thandle;
   ST arrat[0..5]  :TMyread;
 //创建传输线程        For I := 0 to  TreadNum-1 do
        begin
            ST[i] := TMyread.Create(AAdrr,FPort) ;
            FEvent[I] := ST[i].Handle ;
        end;        //等待线程完成
        WaitForMultipleObjects(TreadNum, @ST, True, INFINITE);

解决方案 »

  1.   

    可以定义一个全局变量来记录线程的数量:创建一个线程变量加1(create 里面写),消失(ontermite里面写)后减1,等到变量值为0时再执行你的代码。
      

  2.   

    如你的要求, 如果設置 FreeOnTerminate 為 true 應該可以
      

  3.   

    var
       FEvent array[0..5]  :Thandle;
       ST array[0..5]  :TMyread;
     //创建传输线程        For I := 0 to  TreadNum-1 do
            begin
                ST[i] := TMyread.Create(AAdrr,FPort) ;            
                FEvent[I] := WSACreateEvent();  
                ST[i].xxx ;= FEvent[I];//这样才可以!在TMyread里面要加一个public的WSAEVENT变量
      
            end;        //等待线程完成
            WaitForMultipleObjects(TreadNum, @ST, True, INFINITE);
      

  4.   

    //等待线程完成
            WaitForMultipleObjects(TreadNum, @FEvent[0], True, INFINITE);
      

  5.   

    先CreateEvent
    然后子线程结束时SetEvent 
    所有子线程结束就会触发WaitForMultipleObjects(TreadNum, @FEvent[0], True, INFINITE);了
      

  6.   

    请问 flyinwuhan(制怒·三思而后行) ,我有点不明白
    在TMyread里面要加一个public的WSAEVENT变量 ,这个变量为Thandle类型的就可以了吗?
      

  7.   

    >>这个变量为Thandle类型的就可以了吗?
    YES
      

  8.   

    谢谢 flyinwuhan(制怒·三思而后行) ,我先测试一下
      

  9.   

    flyinwuhan(制怒·三思而后行) :
    大侠,能详细解析下下面的几句什么作用么?看不懂啊,thanks            ST[i] := TMyread.Create(AAdrr,FPort) ;            
                FEvent[I] := WSACreateEvent();  
                ST[i].xxx ;= FEvent[I];//这样才可以!在TMyread里面要加一个public的WSAEVENT变量
      

  10.   

    还有,WaitForMultipleObjects这个我怎么在帮助里面找不到啊?请各位指教下
      

  11.   

    WSACreateEvent在那个单元中啊,怎么找不到?
      

  12.   

    我的测试如A 下:
    unit Unit2;
    interfaceusesClasses, Windows,winsock,shellapi;//"Worker thread declaration"typeTTestThr = class(TThread)private{ Private declarations }protectedprocedure Execute; override;
    Public
        Event:Thandle;end;//Wait thread declarationtypeTWaitThr = class(TThread)privateprocedure UpdateLabel;//this just sets the label's captionprotectedprocedure Execute; override;end;implementationuses unit1;{ TTestThr }procedure TTestThr.Execute;varI : Integer;beginFreeOnTerminate := True;for I := 0 to 39 doSleep(500);SetEvent(Event);end;procedure TWaitThr.UpdateLabel;beginForm1.Label1.Caption := 'Not Waiting';end;procedure TWaitThr.Execute;varhndlArr : Array[0..4] of THandle;thrArr : Array[0..4] of TTestThr;I : Integer;beginFreeOnTerminate := True;for I := 0 to 4 do begin
    begin    thrArr[I] := TTestThr.Create(False);
        hndlArr[I]:= CreateEvent(nil, True, False, nil);
        thrArr[I].Event  := hndlArr[I];
    end;//Sleep(1000); //stagger creation of the threads
    end;WaitForMultipleObjects(5, @thrArr[0] , false, INFINITE);Synchronize(UpdateLabel);
    end;end.
    unit1为:
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    Label1.Caption := 'Waiting';
    Label1.Refresh ;TWaitThr.Create(False);end;
    我对程序进行了跟踪,发现主程序并没有等待子程序,而是不管子程序是否完成,就马上进行下去了
    flyinwuhan(制怒·三思而后行) 我错在那里?
      

  13.   

    错了
    WaitForMultipleObjects(5, @thrArr[0] , false, INFINITE);
    改为
    WaitForMultipleObjects(5, @thrArr[0] ,true, INFINITE);
    也不行
      

  14.   

    unit Unit2;
    interface
    usesClasses, Windows,winsock,shellapi;//"Worker thread declaration"typeTTestThr = class(TThread)
    private
    { Private declarations }
    protected
      procedure Execute; override;
    Public
        Event:Thandle;
    end;//Wait thread declarationtypeTWaitThr = class(TThread)privateprocedure UpdateLabel;//this just sets the label's captionprotectedprocedure Execute; override;end;implementationuses unit1;{ TTestThr }procedure TTestThr.Execute;
    var
    I : Integer;
    begin
    FreeOnTerminate := True;
    for I := 0 to 39 do
    Sleep(500);
    SetEvent(Event);
    end;procedure TWaitThr.UpdateLabel;
    begin
    Form1.Label1.Caption := 'Not Waiting';
    end;procedure TWaitThr.Execute;
    var
    hndlArr : Array[0..4] of THandle;
    thrArr : Array[0..4] of TTestThr;
    I : Integer;
    begin
    FreeOnTerminate := True;
    for I := 0 to 4 do begin
    begin
        thrArr[I] := TTestThr.Create(False);//这里要改成true,先让它休眠!先不执行!
        hndlArr[I]:= CreateEvent(nil, True, False, nil);
        thrArr[I].Event  := hndlArr[I];
        thrArr[I].resume;//等事件句柄传递过去再唤醒这个线程
    end;//Sleep(1000); //stagger creation of the threads
    end;WaitForMultipleObjects(5, @thrArr[0] , true, INFINITE);Synchronize(UpdateLabel);
    end;end.
      

  15.   

    flyinwuhan(制怒·三思而后行)  我将代码copy过去,还是不行啊,但如下却可以了,谁来解释一下
    unit Unit2;
    interfaceusesClasses, Windows,winsock,shellapi;//"Worker thread declaration"typeTTestThr = class(TThread)private{ Private declarations }protected
    constructor Create(ANum:integer); virtual;
    procedure Execute; override;
    Public
        FHandle:integer;end;//Wait thread declarationtypeTWaitThr = class(TThread)privateprocedure UpdateLabel;//this just sets the label's captionprotectedprocedure Execute; override;end;
    varhndlArr : Array[0..4] of THandle;implementationuses unit1;{ TTestThr }constructor TTestThr.Create(ANum: integer);
    begin
     inherited Create(false);
    end;procedure TTestThr.Execute;varI : Integer;beginFreeOnTerminate := True;for I := 0 to 39 do
        Sleep(50);SetEvent(hndlArr[Fhandle]);
    end;procedure TWaitThr.UpdateLabel;beginForm1.Label1.Caption := 'Not Waiting';end;procedure TWaitThr.Execute;varthrArr : Array[0..4] of TTestThr;I : Integer;beginFreeOnTerminate := True;for I := 0 to 4 do begin
    begin    thrArr[I] := TTestThr.Create(1);
        hndlArr[I]:= CreateEvent(nil, True, False, nil);
        thrArr[I].FHandle := i;
    end;end;
    WaitForMultipleObjects(5, @hndlArr , true, INFINITE);
    Synchronize(UpdateLabel);
    end;end.
      

  16.   

    不需要Event.
    不能Wait TThread,只能Wait 线程的句柄.
    代码如:
    var
      Handles: array[0..5] of THandle;
    begin
      For I := 0 to  TreadNum-1 do begin
        with TMyread.Create(AAdrr,FPort) do begin
          FreeOnTerminate:=true;
          Handles[i] := Handle ;
          Resume;                      //最好生成时Suspended
        end;
      End;
        ...
      //等待线程完成
      WaitForMultipleObjects(TreadNum, @Handles[0], True, INFINITE);
      //也可以用MsgWaitForMultipleObjects,
      //这样只要向执行Wait的线程Post一个消息就可以中止Wait.
      

  17.   

    补充一下,线程生成时必须是Suspended的,否则在Create和之后的赋值之间,线程可能已经执行完,不存在了.
      

  18.   

    查了下SDK, WaitForMultipleObjects其实可以等待很多种句柄,而不仅仅是hEvent, 呵呵,谢谢sspeak的提醒:
     
    Change notification
    Console input
    Event
    Mutex
    Process
    Semaphore
    Thread---〉 A thread object's state is signaled when the thread terminates.
    Timer
    是没有必要CreatEvent.