如何计算终止线程?

时间:2014-09-05 10:09:34

标签: multithreading delphi delphi-7

你好朋友我对线程数有疑问。我有一些代码写在线程

Procedure Mainthread.execute;
 var
    I  :    integer;
    ScannerCh : array  of ScannerChild;  //array of ScannerChild
  IpList : TStringlist;
  IPs: Integer;   //ipcount is count of iplist
Begin
       IpList:=TStringList.Create;//creating stringlist
       IPs := IpList.Count; //Ipcount is given value of iplists count
       SetLength(ScannerCh, IPs);  //Setting length of scannerch as ipcount
       I:=0;
        Repeat
          While getthreadscount(getcurrentprocessid) >= tcount + 1(for main thread + Scannerch threads) do  //Checking if  is greater than tcount(thread input) by user
            Sleep(30);
          ScannerCh[I]:=ScannerChild.Create(True, IpList[i]);
          ScannerCh[I].FreeOnTerminate:=True;

          ScannerCh[I].LvHostname := LvHosts;
          ScannerCh[I].Resume;

          I:=I+1;
          Sleep(20);   //Sleep after each thread is created so that threads will enter critical section properly
       until I = IPs;
 end;

Scannerchild线程做了一些工作。如果我只有这些线程在进行中,我的代码将完美运行。如果有一些其他线程在运行,那么我将无法通过getthreadscount函数获取threadscount,我将无法知道哪些线程被getthreadcount函数终止。那么如何为许多线程工作增强我的代码。我的逻辑是当scanch线程终止时它应该减少count变量,当它被创建时它应该增加count变量。因此,如果其他线程被终止,它将不会有任何问题。我只想处理scanner的线程终止,需要获取scanch运行线程实例的计数。所以我把count变量而不是getthreadscount,我的问题将被解决

1 个答案:

答案 0 :(得分:1)

嗯,问题很容易回答。在主线程类中声明一个count变量:

FScannerChildCount: Integer;

每当您创建新线程时,请增加此变量。每当线程终止时,减少它。

由于您在主线程代码中非常清楚且明确地创建了线程,因此增量很容易。

对于递减,您需要为每个扫描程序子线程实例提供OnTerminate事件处理程序。这在进程主线程的上下文中执行,而不是在您的MainThread线程中执行。 FWIW,MainThread是一个可怕的名字,因为每个人都将主线程称为主进程线程。由于OnTerminate事件不会与您的MainThread主题在同一个帖子中运行,因此您需要进行同步。

增加线程时,请使用InterlockedIncrement。当你减少时,使用InterlockedDecrement

OnTerminate处理程序可能如下所示:

procedure MainThread.ScannerChildTerminate(Sender: TObject);
begin
  InterlockedDecrement(FScannerChildCount);
end;

您可以像任何其他事件处理程序一样分配事件:

ScannerCh[I] := ...;
....
ScannerCh[I].OnTerminate := ScannerChildTerminate;
....
ScannerCh[I].Resume;

所有这些都说,虽然这可能是你问的问题的答案,但你试图以错误的方式解决你的问题。您应该使用线程池来简化编码并避免创建和销毁短期线程的开销。