DELPHI -CLISED APPLISS에서 모든 스레드 (TTHREAD) 종료
문제
내 응용 프로그램은 TCP/IP 서버이며 메인 스레드가 한 번만 생성되고 항상 청취됩니다. 새 클라이언트가 연결되면 기본 스레드가 새 스레드를 만듭니다. TClientThread
유형. 그러나 실행중인 클라이언트 스레드 목록은 없습니다. 내 앱이 약간 복잡하게 만들 수 있으므로 스레드가 바쁘더라도 (내 경우 "바쁜"경우에도 모든 스레드에서 "종료"메소드를 실행할 수있는 방법이 있습니까? 시간 초과 세트가 약 30 초인 데이터를 기다리고 있음을 의미합니다. 그래서 기다리지 않고 어쨌든 죽여야합니다.)? 간단한 폐쇄 응용 프로그램은 스레드에서 "종료"메소드를 실행하지 않는 것 같습니다.
해결책
셧다운시 메모리 누출은 걱정할 필요가 없습니다. 운영 체제에 제어를 반환하기 전에 메모리를 풀어주는 데 어려움을 겪는 것은 시간 낭비이며 불필요하게 애플리케이션 종료를 중단합니다. 실제로해야 할 일은 모든 데이터가 저장되었는지 확인하고, 모든 간행 핸들 (예 : 세마포어 및 뮤트)이 올바르게 릴리스되어 나가는 것입니다.
고객에게 알리기 위해 최선을 다하면 다음과 같은 전략이 될 것입니다.
- 모든 클라이언트 처리 스레드를 일부 목록에 어딘가에 추가하십시오 (창조, 파괴 및 반복에 적합한 잠금 장치)
- 클라이언트 스레드가 종료시 목록에서 자신을 제거하고 목록에서 마지막 항목을 이벤트를 설정하도록하십시오 (수동 재설정 이벤트, 예 :
TEvent
syncobjs에서) 서버가 종료되는 경우 - 폴링 소개 (예 :
select
또는 타임 아웃과 동등한) 또는 다른 종류의 중단 (예 : SO_RCVTIMEO / SO_SNDTIMEO)이 장기 실행되는 차단 루틴에서 종료 된 속성을 모니터링합니다. - 종료시 목록을 잠그고 반복하여
Terminate
, 그런 다음 이벤트가 신호를받을 때까지 기다립니다. 물론 목록에 항목을 추가하는 청취 소켓은 목록을 반복하기 전에 닫히고 닫아야합니다.
다른 팁
해당 링크를 클릭하면 볼 수 있습니다.
델파이에서 세마포어 사용, 2 부 : 연결 풀
작성자 : Cary Jensen
초록 : 세마포어는 여러 스레드와 프로세스를 조정하는 데 사용됩니다. 이 세마포어는 공유 리소스에 대한 동시 액세스와 함께 여러 스레드를 제공합니다.
killthreadlist : tlist global을 사용합니다. 내 스레드에서 다음과 같이 모니터링합니다.
while (Not Terminated) do
begin
inc(Inker);
if (WaitForSingleObject(FTick, finterval) = WAIT_TIMEOUT) then
Begin
if Inker >= 10 then
Begin
ProcessTables;
Inker := 0;
sleep(1000);
End;
if KillThreadList.Contains(ThreadID) = True then Terminate;
End;
end;
또한 프로세스에서 killthreadlist를 테스트하여 완료하기 전에 안전하게 수행 할 수 있도록 옵트를 벗어날 수 있습니다.
onterminate 이벤트를 메인 스레드로 전달하고 킬리스트에서 Threadid를 제거합니다. 이 모델을 광범위하게 사용하고 아직 실패하지 않았습니다.
procedure TfrmProcessQualcommLocations.OnTerminateThread;
var
ThreadID : Cardinal;
i : integer;
aStatusBar :TStatFrame;
begin
ThreadID := (Sender as Tthread).ThreadID;
for i := 0 to StatusBarList.Count -1 do
Begin
if StatusBarList.Items[i].ThreadID = ThreadID then
Begin
aStatusBar := StatusBarList.Items[i];
KillThreadList.Extract(ThreadID);
StatusBarList.Extract(aStatusBar);
aStatusBar.Free;
break;
End;
End;
self.Refresh;
end;
위의 경우, 나는 또한 GUI 물건을 제거하고 있습니다.
도움이되기를 바랍니다. SpringerRider