문제

내 응용 프로그램은 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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top