Wann wird ein Prozess terminiert?


Ja, wann wird unter Windows eigentlich ein Prozess beendet? Nun die Frage scheint auf den ersten Blick recht einfach zu beantworten sein mit einem Blick in das PSDK (Stand März 2005):

How Processes are Terminated
A process executes until one of the following events occurs:
- Any thread of the process calls the ExitProcess function.
- The primary thread of the process returns.
- The last thread of the process terminates.
- Any thread calls the TerminateProcess function with a handle to the process.
- For console processes, the default console control handler calls ExitProcess when the console receives a CTRL+C or CTRL+BREAK signal.
- The user shuts down the system or logs off.

Scheint also klar zu sein und bisher dachte ich auch dass es eigentlich so wäre, wie es im PSDK steht. Aber gerade wurde ich eines besseren belehrt. Folgende Situation:

Ich hatte eine zweiten Thread neben dem Haupthread erstellt und gestartet. In diesem Thread wurde mit WaitForSingleObject darauf gewartet bis ein Event signalisiert. Da WaitForSingleObject erst zurückkehrt, wenn das Objekt signalisiert, der Intervall abgelaufen ist oder der Aufruf fehlschlägt, habe ich den entsprechenden Code eben in einen Thread ausgelagert. Soweit kein Problem bisher. Nun musste ich aber feststellen, dass wenn ich das Fenster schließe und somit den Hauptthread beende, der Prozess im Taskmanger immer noch aufgelistet wird, also er offenbar noch ausgeführt wird und eben nicht durch Beenden des Hauptthreads terminiert wurde, wie es die Dokumentation behauptet. Damit der Prozess sauber beendet wurde, musste ich also bevor der Hauptthread terminiert, vorher den entsprechenden Thread beenden. Als ich dies getan hatte, da wurde dann auch der Prozess korrekt terminiert.

Punkt zwei in der obigen Liste ist also offensichtlich falsch. Ein Prozess wird nicht terminiert, wenn der Hauptthread beendet wird, sondern erst wenn alle Threads des Prozesses beendet wurden. Zufälligerweise bin ich über den entsprechenden Eintrag im MSDN gestossen: Terminating a Process und siehe da, die Liste wurde offensichtlich korrigiert und Punkt zwei wurde aus der Liste entfernt. Zusätzlich wurde ein Hinweis bezüglich der C run-time Bibliothek hinzugefügt:

Note that some implementation of the C run-time library (CRT) call ExitProcess if the primary thread of the process returns.

Unter Delphi (Delphi 6 Professional) scheint die VCL allerdings ExitProcess nicht aufzurufen, wenn der Hauptthread beendet oder das Hauptfenster geschlossen wird. Auf der einen Seite ist dieses Verhalten natürlich konform zur Win32 API Dokumentation und somit das Verhalten transparent für den Programmierer, aber auf der anderen Seite, was ist die Intention des Programmierers, wenn er den Hauptthread beendet? Er will offensichtlich den Prozess beenden.

2010-12-29T23:44:53 +0100, mail+homepage[at]michael-puff.de