Gibt es eine Möglichkeit zu überprüfen, ob eine PID einem gültigen Prozess entspricht? Ich erhalte eine PID von einer anderen Quelle als von os.getpid()
und muss überprüfen, ob auf dem Computer kein Prozess mit dieser PID vorhanden ist.
Ich brauche es, um unter Unix und Windows verfügbar zu sein. Ich überprüfe auch, ob die PID NICHT verwendet wird.
Antworten:
Das Senden des Signals 0 an eine PID löst eine OSError-Ausnahme aus, wenn die PID nicht ausgeführt wird, und führt nichts anderes aus.
quelle
os.kill(pid, 0)
ist das gleiche wieos.kill(pid, signal.CTRL_C_EVENT)
die den Prozess beenden kann (oder nicht). Ich bekomme einOSError
Wo,errno==EINVAL
wenn ich dies in einem Unterprozess versuche.Schauen Sie sich das
psutil
Modul an:Es hat eine Funktion namens
pid_exists()
, mit der Sie überprüfen können, ob ein Prozess mit der angegebenen PID vorhanden ist.Hier ist ein Beispiel:
Als Referenz:
quelle
psutil
implementierenpid_exists()
. Vergleiche mit @ Giampaolo Rodolàs Antwort (Autor vonpsutil
)mluebke Code ist nicht 100% korrekt; kill () kann auch EPERM (Zugriff verweigert) auslösen. In diesem Fall bedeutet dies offensichtlich, dass ein Prozess vorhanden ist. Das soll funktionieren:
(bearbeitet gemäß den Kommentaren von Jason R. Coombs)
Sie können dies unter Windows nur tun, wenn Sie pywin32, ctypes oder ein C-Erweiterungsmodul verwenden. Wenn Sie mit der Abhängigkeit von einer externen Bibliothek einverstanden sind, können Sie psutil verwenden :
quelle
Die Antworten zum Senden von 'Signal 0' an den Prozess funktionieren nur, wenn der betreffende Prozess dem Benutzer gehört, der den Test ausführt . Andernfalls erhalten Sie
OSError
aufgrund von Berechtigungen eine , auch wenn die PID im System vorhanden ist.Um diese Einschränkung zu umgehen, können Sie überprüfen, ob
/proc/<pid>
Folgendes vorhanden ist:Dies gilt natürlich nur für Linux-basierte Systeme.
quelle
PermissionError
bedeutet, dass pid existiert , erhalten Sie,ProcessLookupError
wenn pid nicht existiert.OSError
aufgrund der verweigerten Erlaubnis kann von anderen unterschieden werden - entweder durch Betrachten von errno oder durch Abfangen der spezialisierterenPermissionError
/ProcessLookupError
Ausnahmen, die sich daraus ergebenOSError
. Darüber hinaus erhalten Sie den Berechtigungsfehler nur, wenn der Prozess vorhanden ist. Daher ist Ihr Beispiel nur eine alternative Methode, die unter Linux und einigen anderen Unices funktioniert, aber nicht vollständiger ist als ein ordnungsgemäßer Aufrufos.kill(pid, 0)
./proc
Prozess wird nur unter Linux beendet, nicht einmal unter BSD oder OSX.In Python 3.3+ können Sie Ausnahmenamen anstelle von errno-Konstanten verwenden. Posix-Version :
quelle
Suchen Sie hier nach einer Windows-spezifischen Methode, um eine vollständige Liste der ausgeführten Prozesse mit ihren IDs abzurufen. Es wäre so etwas wie
Sie können dann überprüfen, welche PID Sie für diese Liste erhalten. Ich habe keine Ahnung von den Leistungskosten, daher sollten Sie dies überprüfen, wenn Sie häufig eine PID-Überprüfung durchführen.
Verwenden Sie für * NIx einfach die Lösung von mluebke.
quelle
Aufbauend auf ntrrgc habe ich die Windows-Version verbessert, damit der Prozess-Exit-Code und die Berechtigungen überprüft werden:
quelle
GetExistCodeProcess
erfordert diePROCESS_QUERY_INFORMATION
undPROCESS_QUERY_LIMITED_INFORMATION
Zugriffsrechte.GetExitCodeProcess
empfängt ein Handle und einen Zeiger und in diesem Beispiel erhält es eineExitCodeProcess
Struktur als zweiten Parameter, wenn es nur ein Zeiger sein sollte.Durch die Kombination von Giampaolo Rodolàs Antwort für POSIX und meiner für Windows habe ich Folgendes erhalten :
quelle
GetExitCodeProcess
und sicherstellen, dass Sie überhaupt Zugriff haben.kernel32.OpenProcess
ist nicht genug. Wie hier ausgeführt : "Wenn der Prozess kürzlich beendet wurde, ist möglicherweise noch eine PID für das Handle vorhanden." Wenn einkernel32.OpenProcess
Wert ungleich Null zurückgegeben wird, müssen wirkernel32.GetExitCodeProcess
den Exit-Code noch weiter überprüfen.In Windows können Sie dies folgendermaßen tun:
Zunächst versuchen Sie in diesem Code, ein Handle für den Prozess mit der angegebenen PID zu erhalten. Wenn das Handle gültig ist, schließen Sie das Handle für den Prozess und geben Sie True zurück. Andernfalls geben Sie False zurück. Dokumentation für OpenProcess: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx
quelle
Dies funktioniert unter Linux, wenn Sie beispielsweise überprüfen möchten, ob Banshee ausgeführt wird ... (Banshee ist ein Musikplayer)
quelle
os.kill(pid, 0)
oder Betrachtung/proc/{pid}
. Anstatt einen Systemaufruf auszuführen, gibt Ihr Code ein Kind aus, führt eine Shell in diesem Kind aus, die Shell interpretiert Ihr überflüssiges Mini-Shell-Skript, die Shell gibt ein anderes Kind aus, das pgrep ausführt und schließlich pgrep wiederholt/proc
. Ihre Antwort beantwortet die gestellte Frage nicht. Das OP fragte nach einer Methode mit einer PID. Ihre Methode erfordert einen Prozessnamen.Ich würde sagen, verwenden Sie die PID für jeden Zweck, den Sie erhalten, und behandeln Sie die Fehler ordnungsgemäß. Ansonsten ist es ein klassisches Rennen (die PID kann gültig sein, wenn Sie überprüfen, ob sie gültig ist, aber einen Moment später verschwinden)
quelle