Beenden eines Prozesses
Das Beenden eines Prozesses hat die folgenden Ergebnisse:
- Alle verbleibenden Threads im Prozess sind für die Beendigung markiert.
- Alle vom Prozess zugeordneten Ressourcen werden freigegeben.
- Alle Kernelobjekte sind geschlossen.
- Der Prozesscode wird aus dem Arbeitsspeicher entfernt.
- Der Prozessausgangscode ist festgelegt.
- Das Prozessobjekt wird signalisiert.
Während offene Handles für Kernelobjekte automatisch geschlossen werden, wenn ein Prozess beendet wird, sind die Objekte selbst vorhanden, bis alle geöffneten Handles für sie geschlossen werden. Daher bleibt ein Objekt gültig, nachdem ein Prozess, der es verwendet, beendet wird, wenn ein anderer Prozess über ein geöffnetes Handle verfügt.
Die GetExitCodeProcess-Funktion gibt die Beendigung status eines Prozesses zurück. Während ein Prozess ausgeführt wird, wird sein status STILL_ACTIVE. Wenn ein Prozess beendet wird, ändert sich seine Beendigung status von STILL_ACTIVE zum Exitcode des Prozesses.
Wenn ein Prozess beendet wird, wird der Status des Prozessobjekts signalisiert, sodass alle Threads freigegeben werden, die auf das Beenden des Prozesses gewartet haben. Weitere Informationen zur Synchronisierung finden Sie unter Synchronisieren der Ausführung mehrerer Threads.
Wenn das System einen Prozess beendet, werden keine untergeordneten Prozesse beendet, die der Prozess erstellt hat. Das Beenden eines Prozesses generiert keine Benachrichtigungen für WH_CBT Hookprozeduren.
Verwenden Sie die SetProcessShutdownParameters-Funktion , um bestimmte Aspekte der Prozessbeendigung beim Herunterfahren des Systems anzugeben, z. B. wann ein Prozess relativ zu den anderen Prozessen im System beendet werden soll.
So werden Prozesse beendet
Ein Prozess wird bis zu einem der folgenden Ereignisse ausgeführt:
- Jeder Thread des Prozesses ruft die ExitProcess-Funktion auf. Beachten Sie, dass eine Implementierung der C-Laufzeitbibliothek (CRT) ExitProcess aufruft, wenn der primäre Thread des Prozesses zurückgibt.
- Der letzte Thread des Prozesses wird beendet.
- Jeder Thread ruft die TerminateProcess-Funktion mit einem Handle für den Prozess auf.
- Für Konsolenprozesse ruft der Standard-KonsolensteuerelementhandlerExitProcess auf, wenn die Konsole ein STRG+C- oder STRG+BREAK-Signal empfängt.
- Der Benutzer fährt das System herunter oder meldet sich ab.
Beenden Sie einen Prozess nur, wenn sich seine Threads in bekannten Zuständen befinden. Wenn ein Thread auf ein Kernelobjekt wartet, wird er erst beendet, wenn die Wartezeit abgeschlossen ist. Dies kann dazu führen, dass die Anwendung nicht mehr reagiert.
Der primäre Thread kann das Beenden anderer Threads vermeiden, indem er sie anweisen, ExitThread aufzurufen, bevor der Prozess beendet wird (weitere Informationen finden Sie unter Beenden eines Threads). Der primäre Thread kann auch danach ExitProcess aufrufen, um sicherzustellen, dass alle Threads beendet werden.
Der Exitcode für einen Prozess ist entweder der im Aufruf von ExitProcess oder TerminateProcess angegebene Wert oder der Wert, der von der Standard- oder WinMain-Funktion des Prozesses zurückgegeben wird. Wenn ein Prozess aufgrund einer schwerwiegenden Ausnahme beendet wird, ist der Exitcode der Wert der Ausnahme, die die Beendigung verursacht hat. Darüber hinaus wird dieser Wert als Exitcode für alle Threads verwendet, die ausgeführt wurden, als die Ausnahme aufgetreten ist.
Wenn ein Prozess von ExitProcess beendet wird, ruft das System die Einstiegspunktfunktion jeder angefügten DLL mit einem Wert auf, der angibt, dass der Prozess von der DLL getrennt wird. DLLs werden nicht benachrichtigt, wenn ein Prozess von TerminateProcess beendet wird. Weitere Informationen zu DLLs finden Sie unter Dynamic-Link Libraries.
Wenn ein Prozess durch TerminateProcess beendet wird, werden alle Threads des Prozesses sofort beendet, ohne dass zusätzlichen Code ausgeführt werden kann. Dies bedeutet, dass der Thread keinen Code in Beendigungshandlerblöcken ausführt. Darüber hinaus werden keine angefügten DLLs benachrichtigt, dass der Prozess getrennt wird. Wenn ein Prozess einen anderen Prozess beendet, bieten die folgenden Schritte eine bessere Lösung:
Lassen Sie beide Prozesse die RegisterWindowMessage-Funktion aufrufen, um eine private Nachricht zu erstellen.
Ein Prozess kann den anderen Prozess beenden, indem er eine private Nachricht mit der BroadcastSystemMessage-Funktion wie folgt sendet:
DWORD dwRecipients = BSM_APPLICATIONS; UINT uMessage = PM_MYMSG; WPARAM wParam = 0; LPARAM lParam = 0; BroadcastSystemMessage( BSF_IGNORECURRENTTASK, // do not send message to this process &dwRecipients, // broadcast only to applications uMessage, // registered private message wParam, // message-specific value lParam ); // message-specific value
Der Prozess, der die private Nachricht empfängt, ruft ExitProcess auf, um die Ausführung zu beenden.
Die Ausführung der Funktionen ExitProcess, ExitThread, CreateThread, CreateRemoteThread und CreateProcess wird innerhalb eines Adressraums serialisiert. Es gelten folgende Einschränkungen:
- Während der Prozessstart- und DLL-Initialisierungsroutinen können neue Threads erstellt werden, sie beginnen jedoch erst mit der Ausführung, wenn die DLL-Initialisierung für den Prozess abgeschlossen ist.
- Es kann jeweils nur ein Thread in einer DLL-Initialisierungs- oder Detach-Routine enthalten sein.
- Die ExitProcess-Funktion gibt erst zurück, wenn sich keine Threads in ihren DLL-Initialisierungs- oder Trennroutinen befinden.