Pergunta

Meu aplicativo é um servidor TCP / IP, com thread principal criado apenas uma vez e ouvindo o tempo todo. Quando um novo cliente se conecta, o thread principal cria o novo segmento do tipo TClientThread. Contudo, não há lista de execução tópicos cliente, como que faria meu aplicativo um pouco complicado ... existe alguma maneira de executar "terminar" método em todos os segmentos, mesmo se o segmento está ocupado (no meu caso "ocupado" meios que está esperando os dados, onde o conjunto de tempo limite é cerca de 30 segundos ... então eu tenho que matá-lo de qualquer maneira, sem esperar.)? A aplicação simples de encerramento parece não correr "terminar" método sobre os tópicos, o que acaba com vazamentos de memória relatado por FastMM ...

Foi útil?

Solução

Os vazamentos de memória no desligamento não são nada com que se preocupar - ir para a dificuldade de liberação de memória antes de retornar controle para o sistema operacional é um desperdício de tempo e atrasa inutilmente saída do aplicativo. Tudo que você realmente precisa fazer é garantir que todos os dados foram salvos, e todos os identificadores entre processos (tais como semáforos e semáforos) lançado corretamente, e sair de distância.

Para notificar os clientes, o melhor que você pode fazer seria uma estratégia mais ou menos assim:

  • Adicione os tópicos de tratamento de cliente para alguns lista em algum lugar (com bloqueio adequado na criação, destruição e iteração)
  • Faça threads cliente retirar-se da lista após a rescisão, e ter o último item removido da lista definir um evento (evento reset manual, por exemplo TEvent em SyncObjs) se o servidor está sendo desligado
  • Apresente polling (por exemplo select ou equivalente com um tempo limite) ou outro tipo de interrupção (por exemplo SO_RCVTIMEO / SO_SNDTIMEO) no que de outra forma seriam longa rotinas de bloqueio, monitorando a propriedade Terminado
  • No encerramento, bloquear a lista e iterate através dele, chamando Terminate, e depois esperar para o evento a ser sinalizado; é claro, o socket de escuta que acrescenta itens à lista deve ser fechado e conhecido por ser fechado antes de a iteração através da lista

Outras dicas

soa como este artigo pode ajudar

O que você vai ver se você clicar nesse link:

Usando semáforos em Delphi, Parte 2: O pool de conexão

Por: Cary Jensen

Abstract: Semáforos são usados ??para coordenar vários segmentos e processos. Que os semáforos fornecem vários segmentos com simultânea acesso a um recurso compartilhado é com destaque para o classe TFixedConnectionPool descrito neste artigo.

Eu uso um KillThreadList: TList global. I monitorá-lo na minha lista de discussão como:

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;

Eu também teste para a KillThreadList nos meus processos para deixar-me optar por sair de-los antes da conclusão, onde seguro fazê-lo.

I passar o evento OnTerminate para o segmento principal e retire a ThreadID do KillList lá. Eu uso este modelo extensivamente e não me falhou ainda.

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;

No caso acima, também estou removendo algumas coisas GUI.

Espero que ajude. SpringerRider

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top