Schneller Weg um festzustellen, ob eine PID (Windows) existiert?

8

Ich realisiere "schnell" ist ein bisschen subjektiv, also werde ich mit etwas Kontext erklären. Ich arbeite an einem Python-Modul mit dem Namen psutil zum Lesen von Prozessinformationen in einer Plattform Weg. Eine der Funktionen ist eine pid_exists(pid) -Funktion zum Bestimmen, ob sich eine PID in der aktuellen Prozessliste befindet.

Im Moment mache ich das offensichtlich, indem ich EnumProcesses () um die Prozessliste zu ziehen, dann durch die Liste zu interviewen und nach der PID zu suchen. Einige einfache Benchmarks zeigen jedoch, dass dies auf UNIX-basierten Plattformen (Linux, OS X, FreeBSD) wesentlich langsamer ist als die pid_exists-Funktion, in der wir kill(pid, 0) mit einem 0-Signal verwenden, um festzustellen, ob eine PID existiert. Zusätzliche Tests zeigen, dass EnumProcesses fast die ganze Zeit in Anspruch nimmt.

Wer weiß einen schnelleren Weg als die Verwendung von EnumProcesses, um festzustellen, ob eine PID existiert? Ich habe OpenProcess () ausprobiert und nach einem Fehler beim Öffnen des nicht vorhandenen Prozesses gesucht. aber das war mehr als 4x langsamer als durch die EnumProcesses Liste zu laufen, so dass es auch heraus ist. Irgendwelche anderen (besseren) Vorschläge?

HINWEIS : Dies ist eine Python-Bibliothek, die lib-Abhängigkeiten von Drittanbietern wie pywin32-Erweiterungen vermeiden soll. Ich brauche eine Lösung, die schneller ist als unser aktueller Code, und das hängt nicht von pywin32 oder anderen Modulen ab, die in einer Standard-Python-Distribution nicht vorhanden sind.

BEARBEITEN : Um es klar zu stellen - wir sind uns bewusst, dass es bei der Leseprozessanalyse Race Conditions gibt. Wir erheben Ausnahmen, wenn der Prozess im Laufe der Datenerfassung aufhört oder wir auf andere Probleme stoßen. Die Funktion pid_exists () soll die ordnungsgemäße Fehlerbehandlung nicht ersetzen.

UPDATE : Anscheinend waren meine früheren Benchmarks fehlerhaft - ich schrieb einige einfache Test-Apps in C und EnumProcesses kommt immer langsamer und OpenProcess (in Verbindung mit GetProcessExitCode, falls die PID gültig ist, aber der Prozess hat gestoppt) ist eigentlich viel schneller nicht langsamer.

    
Jay 26.02.2009, 20:19
quelle

4 Antworten

8

OpenProcess könnte Ihnen sagen, dass Sie alle aufzählen möchten. Ich habe keine Ahnung, wie schnell.

BEARBEITEN : Beachten Sie, dass Sie auch GetExitCodeProcess benötigen, um den Status des Prozesses zu überprüfen, selbst wenn Sie ein Handle von OpenProcess erhalten.

    
Sanjaya R 26.02.2009, 22:41
quelle
4

Bei der Verwendung der Funktion pid_exists gibt es eine inhärente Race-Bedingung: Wenn das aufrufende Programm die Antwort verwendet, ist der Prozess möglicherweise bereits verschwunden oder ein neuer Prozess mit der abgefragten ID wurde möglicherweise erstellt. Ich würde sagen, dass jede Anwendung, die diese Funktion verwendet, vom Design her fehlerhaft ist und dass sich die Optimierung dieser Funktion daher nicht lohnt.

    
zvrba 26.02.2009 21:08
quelle
3

Es stellte sich heraus, dass meine Benchmarks offensichtlich fehlerhaft waren, da spätere Tests ergeben, dass OpenProcess und GetExitCodeProcess viel schneller sind als EnumProcesses. Ich bin mir nicht sicher, was passiert ist, aber ich habe einige neue Tests durchgeführt und festgestellt, dass dies die schnellere Lösung ist:

%Vor%

Beachten Sie, dass Sie GetExitCodeProcess() verwenden müssen, da OpenProcess() für Prozesse erfolgreich ist, die vor Kurzem gestorben sind, sodass Sie nicht davon ausgehen können, dass ein gültiger Prozess-Handle bedeutet, dass der Prozess ausgeführt wird.

Beachten Sie auch, dass OpenProcess() für PIDs erfolgreich ist, die sich innerhalb von 3 einer gültigen PID befinden (siehe Warum ist OpenProcess erfolgreich, auch wenn ich drei zur Prozess-ID hinzufüge? )

    
Jay 01.03.2009 18:18
quelle
3

Ich würde Jay's letzte Funktion auf diese Weise kodieren.

%Vor%

Der Hauptunterschied besteht im Schließen des Prozess-Handles (wichtig, wenn der Client dieser Funktion lange läuft) und in der Prozessbeendigungs-Erkennungsstrategie. WaitForSingleObject gibt Ihnen die Möglichkeit, bis zum Ende des Prozesses eine Weile zu warten (indem Sie den Wert von 0 in einen Funktionsparameter ändern).

    
Eugenio Miró 04.03.2009 02:13
quelle

Tags und Links