eingefrorenen Thread vom Hauptprogramm aus beenden - wie?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Bitschubser
Beiträge: 62
Registriert: Mo 27. Aug 2012, 15:43

eingefrorenen Thread vom Hauptprogramm aus beenden - wie?

Beitrag von Bitschubser »

Hallo,

Eins vorweg:
Ja, mir ist klar dass man mit Thread.Terminate den Thread nett bitten soll sich zu beenden, natürlich in der Thread.Execute auf Terminated prüft und das ganze nach Geschmack mit FreeOnTerminate := false oder true kombiniert und dann eben im Hauptprogramm wenn der Thread sich beendet hat entsprechend Thread.Destroy aufruft oder eben nicht.

Nur – was ist wenn der Thread in einer Enlosschleife festhängt, und von daher an der Stelle in der Thread.Execute wo auf Terminated geprüft wird gar nicht vorbeikommt?
Und weiter angenommen, es wäre für mein Programm besser, einfach den klemmenden Thread neuzustarten als das ganze Programm (was ja nicht so schwierig umzusetzen wäre).

Was ich probiert hab (alles in einer Konsolenanwendung unter Linux):

Code: Alles auswählen

KillThread(Thread.Handle) 
-> keine Wirkung (Anzahl Threads unter /proc/????/status unverändert, trotz Rückgabewert 0

Code: Alles auswählen

ThreadManager := GetThreadManager;
ThreadManager.KillThread(Thread.Handle) 
-> keine Wirkung (Anzahl Threads unter /proc/????/status unverändert, trotz Rückgabewert 0

Code: Alles auswählen

Thread.Destroy 
// bzw. 
FreeAndNIL(Thread) 
(egal ob vorher KillThread aufgerufen wird oder nicht) führen dazu, dass das Hautprogramm nicht mehr ausgeführt wird (im Debugger wie auch stand-alone), auch hier bleibt die Anzahl der Threads unter /proc/????/status aber unverändert.

Code: Alles auswählen

RemoveThread
(der so wie das in den Sourcen aussieht genau das macht was ich bräuchte) exisitert ja anscheinend nur auf Plattformen mit selbstgestrickter Thread-Verwaltung?


Gruß, Ingo

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: eingefrorenen Thread vom Hauptprogramm aus beenden - wie

Beitrag von Socke »

Bitschubser hat geschrieben:Nur – was ist wenn der Thread in einer Enlosschleife festhängt, und von daher an der Stelle in der Thread.Execute wo auf Terminated geprüft wird gar nicht vorbeikommt?
Und weiter angenommen, es wäre für mein Programm besser, einfach den klemmenden Thread neuzustarten als das ganze Programm (was ja nicht so schwierig umzusetzen wäre).
Dann bleiben dir wohl zwei Möglichkeiten
  • Den Thread in einen eigenen Prozess auslagern. Den Prozess kann das Betriebssystem einfach abschießen. Bei Threads ist das offensichtlich nicht der Fall.
  • Den Thread selbst ändern. Wenn du aufgrund deiner Klassenstruktur nicht auf Terminated prüfen kannst, kannst du auch einfach eine Exception werfen.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: eingefrorenen Thread vom Hauptprogramm aus beenden - wie

Beitrag von marcov »

Manchmal kann man das umgehen mit waitformultiple.

Zb, oft wenn einen Thread Blocked, dann Blocked die irgendwo auf eine Handle (File, Pipe, Socket usw) mit zb Waitforsingle.

Die Lösung ist dann diese Code zu finden und modifizieren nach waitformultiple, der dazu auch wartet es auch den Handle von ein TEvent.

Dann kann man mit event.signal das Blocken beenden, und dann mit den Terminated Kontrolle raus.

Aber das funktioniert nur wenn das Blocken im heutigen Prozess stattfinden, und man dafür Quellen hat. Und eben dann ist nicht echt einfach.

Antworten