Delphi - beenden alle Fäden (TThread) beim Schließen Anwendung
Frage
Meine Anwendung ist ein TCP / IP-Server, mit Haupt-Thread nur einmal erstellt und die ganze Zeit zu hören. Wenn neue Client eine Verbindung herstellt, erstellt der Haupt-Thread die neuen Thread von TClientThread
Typ. Es gibt jedoch keine Liste Client-Threads ausgeführt wird, wie das wäre meine app ein wenig kompliziert zu machen ... ist es eine Möglichkeit, „beenden“ Methode auf alle Threads auszuführen, auch wenn der Thread beschäftigt ist (in meinem Fall „besetzt“ bedeutet es für die Daten warten, wo die Timeout-Set etwa 30 Sekunden ist ... Wie auch immer, ich muss es töten, ohne zu warten.)?
Die einfache Schließung Anwendung scheint nicht „beenden“ -Methode an den Fäden zu laufen, die mit Speicherlecks gemeldet endet durch FastMM ...
Lösung
Speicherverluste beim Herunterfahren sind nichts zu befürchten - geht die Mühe Speicherfreigabe, bevor die Steuerung an das Betriebssystem zurück eine Verschwendung von Zeit und verlangsamen unnötig nach unten Anwendung beenden. Alles, was Sie wirklich tun müssen, ist sicherzustellen, dass alle Daten gespeichert wurden, und alle Intergriffe (wie Semaphore und Mutex) korrekt freigegeben, und Ausfahrt entfernt.
Für Kunden benachrichtigen, das Beste, was Sie tun können, eine Strategie etwas wie das wäre:
- Fügen Sie alle Client-Handling-Threads zu einem gewissen Liste irgendwo (mit geeigneten Verriegelungs auf Schöpfung, Zerstörung und Iteration)
- Erstellen Sie Client-Threads selbst aus der Liste entfernen nach der Kündigung und haben das letzte Element aus der Liste entfernt ein Ereignis aus (manuelles Reset-Ereignis, zum Beispiel
TEvent
in SyncObjs), wenn der Server heruntergefahren - Führen Polling (z
select
oder gleichwertig mit einem Timeout) oder eine andere Art von Unterbrechung (z SO_RCVTIMEO / SO_SNDTIMEO) in welche Routinen sonst wäre lang andauernde Blockierung, die Überwachung der Eigenschaft Terminated - Ein Herunterfahren, sperren Sie die Liste und durchlaufen sie,
Terminate
Aufruf, und dann warten, bis das Ereignis signalisiert werden; natürlich die Abhörsocket, die Elemente zur Liste hinzufügt sollten geschlossen und bekannt sein, geschlossen werden, bevor Sie durch die Liste iterieren
Andere Tipps
Klingt wie dieser Artikel helfen kann
Was Sie sehen, wenn Sie auf diesen Link klicken:
Mit Semaphore in Delphi, Teil 2: Die Connection Pool
Von: Cary Jensen
Abstract: Semaphore verwendet werden, um mehrere Threads koordinieren und Prozesse. Das Semaphore bieten mehrere Threads bei gleichzeitiger Zugriff auf eine gemeinsam genutzte Ressource ist, durch die markierte TFixedConnectionPool Klasse beschrieben in diesem Artikel.
Ich verwende eine KillThreadList: TList global. Ich beobachte es in meinem Thread als:
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;
Ich teste auch für die KillThreadList in meine Prozesse mir vor dem Abschluss aus ihnen lassen sich entscheiden, wo sicher, dies zu tun.
Ich gehe das OnTerminate Ereignis, um den Haupt-Thread und entfernen Sie die ThreadID vom KillList dort. Ich benutze dieses Modell ausgiebig und es hat mich noch nicht gescheitert.
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;
Im obigen Fall, ich entferne auch einig GUI Zeug.
Ich hoffe, das hilft. SpringerRider