Question

Mon application est un serveur TCP / IP, avec le thread principal créé une seule fois & amp; écoute tout le temps. Lorsqu'un nouveau client se connecte, le thread principal crée le nouveau thread de type TClientThread . Il n’existe cependant aucune liste de threads client en cours d’exécution, ce qui compliquerait un peu l’application de mon application. Existe-t-il un moyen quelconque d’exécuter " terminate " méthode sur tous les threads, même si le thread est occupé (dans mon cas, "occupé" signifie qu'il attend les données, le délai d'attente étant d'environ 30 secondes ... je dois donc le tuer quand même, sans attendre.) ? L'application de fermeture simple ne semble pas exécuter "Terminer". méthode sur les threads, ce qui entraîne des fuites de mémoire signalées par FastMM ...

Était-ce utile?

La solution

Les fuites de mémoire à l’arrêt ne vous inquiétez pas: vous libérer de la mémoire avant de rendre le contrôle au système d’exploitation est une perte de temps qui ralentit inutilement la fermeture des applications. Il vous suffit de vous assurer que toutes les données ont été enregistrées et que tous les descripteurs interprocess (tels que les sémaphores et les mutex) sont correctement libérés et sortent.

Pour notifier les clients, le mieux que vous puissiez faire serait une stratégie un peu comme ceci:

  • Ajoutez tous les threads de gestion des clients à une liste quelque part (avec un verrouillage approprié pour la création, la destruction et l'itération)
  • Demandez aux threads clients de se retirer de la liste lors de la résiliation et demandez au dernier élément de la liste de définir un événement (événement de réinitialisation manuelle, par exemple TEvent dans SyncObjs) si le serveur est en train de fermer
  • Introduisez une interrogation (par exemple, select ou un équivalent avec un délai d'attente) ou un autre type d'interruption (par exemple, SO_RCVTIMEO / SO_SNDTIMEO) dans ce qui serait autrement des routines de blocage de longue durée, surveillant la propriété Terminated
  • À l’arrêt, verrouillez la liste et parcourez-la en appelant Terminate , puis attendez que l’événement soit signalé; bien entendu, le socket d’écoute qui ajoute des éléments à la liste doit être fermé et connu pour être fermé avant de parcourir la liste

Autres conseils

Il semble que cet article puisse aider

Ce que vous verrez si vous cliquez sur ce lien:

  

Utilisation des sémaphores dans Delphi, partie 2:   Le pool de connexion

     

Par: Cary Jensen

     

Résumé: Les sémaphores sont utilisés pour   coordonner plusieurs threads et   processus. Que les sémaphores fournissent   plusieurs threads avec simultané   l'accès à une ressource partagée est   mis en évidence par le   La classe TFixedConnectionPool décrite   dans cet article.

J'utilise un KillThreadList: TList global. Je le surveille dans mon thread en tant que:

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;

Je teste également KillThreadList dans mes processus pour me permettre de les désactiver avant la fin du processus, même en toute sécurité.

Je transmets l'événement OnTerminate au thread principal et supprime le ThreadID de la KillList. J'utilise beaucoup ce modèle et il ne m'a pas encore échoué.

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;

Dans le cas ci-dessus, je supprime également certains éléments de l'interface graphique.

J'espère que ça aide. SpringerRider

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top