멀티 스레드 응용 프로그램 (ip 스캐너)에 대해 의문점이 있습니다. 192.168.0.1 192.168.0.1 192.168.0.1 같은 큰 IP 범위 및 스레드 제한을 99로 넣을 때. 그래서 내 응용 프로그램을 실행할 때 (99 스레드 (ScannerChild) + 주 스레드 + Scannerthread) 한 번에 101 스레드를 실행해야하며 스캔 할 때 99 scannerchild와 1 scannethreads가 종료되고 1 스레드 만 그 시간 (메인 스레드)을 실행해야합니다. 하지만 스레드 수가 102로 바뀌고 스캔 스레드 수가 1로 오지 않으면 작업 관리자에서 threadcount가 2로 표시되는 경우가 있습니다. 뭐가 문제 야 ? Scannerthread 에 대한일부 불확실한 스레드가 생성 중이고 종료되지 않습니다.
코드/
/Creating constructor of scannerthread
Constructor ScannerThread.Create(CreateSuspended: Boolean);
Begin
Inherited Create(CreateSuspended);
Freeonterminate:= true; //Freeonterminate is true
End;
{ScannerThread Thread }
procedure ScannerThread.Execute;
var
I : integer;
ScannerCh : array of ScannerChild; //array of ScannerChild
IpList : TStringlist; //Iplist as tstringlist
IPs: Integer; //ipcount is count of iplist
Begin
ScannerchCount:=0; //Initialising scannerchcount as 0
IpList:=TStringList.Create;//creating stringlist
IF GetNumberOfIpsInRange(Ip_From, Ip_To, IpList) Then //Function call that returns iplist if TRUE
Begin
Try
IF Assigned(LvHosts) Then //Clearing LvHosts field
LvHosts.Clear;
IPs := IpList.Count; //Ipcount is given value of iplists count
SetLength(ScannerCh, IPs); //Setting length of scannerch as ipcount
I:=0;
Repeat
While ScannerChcount > tcount-1 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].OnTerminate:= ScanchildTerminated; // Event scanchildterminated occurs on termination of Scannerch thread
ScannerCh[I].LvHostname := LvHosts; //Lhostname is private listview of scannechild
ScannerCh[I].Resume;
ScannerChCount:=Scannerchcount+1; //Incrementing scannerchcounts
I:=I+1;
Sleep(20); //Sleep after each thread is created so that threads will enter critical section properly
until I = IPs;
Scannerch:=nil;
If Assigned(IpList) Then //Free iplist
FreeAndNil(IpList);
Except
On E: Exception do
Begin
ShowMessage('Invalid operation :' + E.Message); //Showexception message
If Assigned(IpList) Then //Free iplist
FreeAndNil(IpList);
end;
End;
End
Else
Begin
Ipscan.lbResult.caption:='Invalid Ip Range';
Exit;
End;
Repeat //Main Thread Waiting For Ip scan Threads to finish
Sleep(100);
until ScannerChCount = 0;
End;
Scannerchild 코드
Constructor ScannerChild.Create(CreateSuspended: Boolean; IP: String);
Begin
Inherited Create(CreateSuspended);
//FCriticalsection := TCriticalSection.create; //Creating critical section
IPToScan:=IP;
End;
//Execution procedure for scannerchild
procedure ScannerChild.Execute;
Var
MainOutput : TListItem;//Listitem variable for adding listitems
Hostname : String; //Hostname is declared as string
Begin
Try
MainOutput:=LvHostname.Items.Add; //Adding items to mainoutput
MainOutput.Caption:=IPToScan;
Hostname := IPAddrToName(IPToScan);
If Hostname <> EmptyStr Then
Begin
MainOutput.SubItems.Add(IPAddrToName(IPToScan)); //Displaying output
End
Else
Mainoutput.subitems.add('No host');
Finally
End;
End;
//this event get called when scannerch thread terminates
procedure Scannerthread.ScanchildTerminated(Sender : TObject);
Begin
ScannerChCount:=ScannerchCount-1; // Decrementing scannerchcount
End;
일부 디버깅을 수행합니다. 닫히지 않을 스레드가 멈추는 부분을 해결할 수있는 진단 코드를 추가하십시오. 디버깅하는 법을 배워야합니다. 그리고 그것은 반드시 디버거에서 의미하는 것은 아닙니다. 추적 디버깅을 추가하십시오. –
그리고 여전히 메인 스레드에서 GUI 컨트롤에 접근하고 있습니다. 여러 번 그 얘기를 들었습니다. 답장을 무시하는 이유는 무엇입니까? 그것은 우리를 괴롭 히고 있습니다. 우리가 너에게 똑같은 말을하고 싶다고 생각하니? 우리는 사람들이 배우는 것을 돕고 보상을 얻습니다. 당신이 듣기가 불가능하다면 우리에게는 보상이 없습니다. 우리의 가치있는 시간을 가지세요. 또한 많은 쓰레드를 만들고 파괴 할 수 있습니다. 100 개의 스레드를 생성하고 완료 될 때까지 작업을 수행하도록하십시오. –