你好朋友我对线程数有疑问。我有一些代码写在线程
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,我的问题将被解决
答案 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;
所有这些都说,虽然这可能是你问的问题的答案,但你试图以错误的方式解决你的问题。您应该使用线程池来简化编码并避免创建和销毁短期线程的开销。