Pregunta

Mi aplicación es un servidor TCP / IP, con el hilo principal creado solo una vez & amp; escuchando todo el tiempo Cuando el nuevo cliente se conecta, el hilo principal crea el nuevo hilo del tipo TClientThread . Sin embargo, no hay una lista de subprocesos en ejecución del Cliente, ya que eso complicaría un poco mi aplicación ... ¿hay alguna forma de ejecutar " terminar? & Quot; Método en todos los subprocesos, incluso si el subproceso está ocupado (en mi caso "ocupado" significa que está esperando los datos, donde el tiempo de espera establecido es de unos 30 segundos ... así que tengo que eliminarlo de todos modos, sin esperar). ? La simple aplicación de cierre parece no ejecutar " terminar " Método en los subprocesos, que termina con pérdidas de memoria reportadas por FastMM ...

¿Fue útil?

Solución

Las pérdidas de memoria en el apagado no son nada de qué preocuparse: preocuparse por liberar la memoria antes de devolver el control al sistema operativo es una pérdida de tiempo y ralentiza innecesariamente la salida de la aplicación. Todo lo que realmente necesita hacer es asegurarse de que todos los datos se hayan guardado y todos los manejadores interproceso (como semáforos y mutexes) liberados correctamente, y salir.

Para notificar a los clientes, lo mejor que puedes hacer sería una estrategia como esta:

  • Agregue todos los subprocesos de manejo del cliente a alguna lista en algún lugar (con un bloqueo adecuado en la creación, destrucción e iteración)
  • Haga que los subprocesos de los clientes se eliminen de la lista al finalizar, y elimine el último elemento de la lista para establecer un evento (evento de restablecimiento manual, por ejemplo, TEvent en SyncObjs) si el servidor se está cerrando
  • Introduzca el sondeo (por ejemplo, select o equivalente con un tiempo de espera) u otro tipo de interrupción (por ejemplo, SO_RCVTIMEO / SO_SNDTIMEO) en lo que de otra manera serían rutinas de bloqueo de larga ejecución, monitoreando la propiedad terminada
  • Al apagar, bloquee la lista e itere a través de ella, llamando a Terminate , y luego espere a que se señale el evento; por supuesto, la toma de escucha que agrega elementos a la lista debe cerrarse y se sabe que está cerrada antes de iterar a través de la lista

Otros consejos

Parece que este artículo puede ayudar

Lo que verás si haces clic en ese enlace:

  

Usando semáforos en Delphi, Parte 2:   El conjunto de conexiones

     

Por: Cary Jensen

     

Resumen: los semáforos se utilizan para   coordinar múltiples hilos y   procesos Que los semáforos proporcionan.   múltiples hilos con simultaneo   El acceso a un recurso compartido es   resaltado por el   Clase TFixedConnectionPool descrita   en este artículo.

Utilizo un KillThreadList: TList global. Lo superviso en mi hilo 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;

También hago pruebas para KillThreadList en mis procesos para que pueda dejar de participar antes de que se complete, donde sea seguro hacerlo.

Transfiero el evento OnTerminate al hilo principal y elimino el ThreadID de la lista de muerte allí. Utilizo este modelo ampliamente y todavía no me ha fallado.

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;

En el caso anterior, también estoy eliminando algunas cosas de GUI.

Espero que ayude. SpringerRider

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top