Czy istnieje sposób, aby sprawdzić, czy pid odpowiada ważnemu procesowi? Otrzymuję pid z innego źródła niż z os.getpid()
i muszę sprawdzić, czy na komputerze nie ma procesu z tym identyfikatorem.
Potrzebuję tego, aby był dostępny w systemach Unix i Windows. Sprawdzam również, czy PID NIE jest używany.
Odpowiedzi:
Wysłanie sygnału 0 do pidu zgłosi wyjątek OSError, jeśli pid nie jest uruchomiony, i nie zrobi nic innego.
źródło
os.kill(pid, 0)
działa tak samo, jakos.kill(pid, signal.CTRL_C_EVENT)
może zakończyć proces (lub zakończyć się niepowodzeniem). DostajęOSError
gdzie,errno==EINVAL
kiedy próbuję tego w podprocesie.Spójrz na
psutil
moduł:Posiada funkcję o nazwie
pid_exists()
, której możesz użyć do sprawdzenia, czy istnieje proces o podanym pid.Oto przykład:
Na przykład:
źródło
psutil
implementuje siępid_exists()
w POSIX . Porównaj z odpowiedzią @Giampaolo Rodolà (autorpsutil
)kod mluebke nie jest w 100% poprawny; kill () może również wywołać EPERM (odmowa dostępu), w którym to przypadku oznacza to oczywiście, że proces istnieje. To ma zadziałać:
(zredagowane zgodnie z komentarzami Jason R. Coombs)
Nie możesz tego zrobić w systemie Windows, chyba że używasz pywin32, ctypes lub modułu rozszerzenia C. Jeśli nie masz nic przeciwko uzależnieniu się od zewnętrznej biblioteki, możesz użyć psutil :
źródło
Odpowiedzi obejmujące wysłanie „sygnału 0” do procesu będą działać tylko wtedy, gdy właścicielem danego procesu jest użytkownik uruchamiający test . W przeciwnym razie otrzymasz uprawnienia
OSError
z powodu uprawnień , nawet jeśli pid istnieje w systemie.Aby ominąć to ograniczenie, możesz sprawdzić, czy
/proc/<pid>
istnieje:Dotyczy to oczywiście tylko systemów opartych na Linuksie.
źródło
PermissionError
oznacza , że pid istnieje , otrzymasz,ProcessLookupError
jeśli pid nie istnieje.OSError
odmowy zgody można odróżnić od innych - patrząc na errno lub wychwytując bardziej wyspecjalizowanePermissionError
/ProcessLookupError
wyjątki, z których wynikająOSError
. Co więcej, błąd uprawnień pojawia się tylko wtedy, gdy proces istnieje. Zatem twój przykład jest po prostu alternatywną metodą, która działa na Linuksie i niektórych innych Uniksach, ale nie jest bardziej kompletna niż prawidłowe wywołanieos.kill(pid, 0)
./proc
procfs wychodzi tylko na Linuksie, nawet nie na BSD lub OSX.W Pythonie 3.3+ można używać nazw wyjątków zamiast stałych errno. Wersja Posix :
źródło
Poszukaj tutaj specyficznego dla systemu Windows sposobu uzyskania pełnej listy uruchomionych procesów wraz z ich identyfikatorami. To byłoby coś takiego
Następnie możesz zweryfikować pid, który otrzymałeś na tej liście. Nie mam pojęcia o kosztach wydajności, więc lepiej sprawdź to, jeśli masz zamiar często przeprowadzać weryfikację pid.
W przypadku * NIx wystarczy użyć roztworu mluebke.
źródło
Opierając się na ntrrgc, wzmocniłem wersję systemu Windows, aby sprawdzała kod zakończenia procesu i szukała uprawnień:
źródło
GetExistCodeProcess
wymagane są prawa dostępuPROCESS_QUERY_INFORMATION
iPROCESS_QUERY_LIMITED_INFORMATION
.GetExitCodeProcess
otrzymuje uchwyt i wskaźnik, aw tym przykładzie otrzymujeExitCodeProcess
strukturę jako drugi parametr, podczas gdy powinien to być tylko wskaźnik.Łącząc odpowiedź Giampaolo Rodolà dla POSIX i moją dla Windows , otrzymałem to:
źródło
GetExitCodeProcess
i upewnić się, że masz nawet dostęp.kernel32.OpenProcess
Samo używanie nie wystarczy. Jak wskazano tutaj , „jeśli proces zakończył się niedawno, pid może nadal istnieć dla uchwytu”. Jeślikernel32.OpenProcess
zwraca wartość różną od zera, nadal musimykernel32.GetExitCodeProcess
sprawdzić kod zakończenia.W systemie Windows możesz to zrobić w następujący sposób:
Przede wszystkim w tym kodzie próbujesz uzyskać uchwyt dla procesu z podanym pid. Jeśli uchwyt jest prawidłowy, zamknij uchwyt dla procesu i zwróć True; w przeciwnym razie zwrócisz False. Dokumentacja dla OpenProcess: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx
źródło
To zadziała na Linuksie, na przykład, jeśli chcesz sprawdzić, czy banshee działa ... (banshee to odtwarzacz muzyki)
źródło
os.kill(pid, 0)
lub patrzenia/proc/{pid}
. Zamiast wykonywać jedno wywołanie systemowe, twój kod rozwidla dziecko, wykonuje powłokę w tym dziecku, powłoka interpretuje twój zbędny mini-skrypt powłoki, powłoka rozwidla kolejne dziecko, które wykonuje pgrep i na końcu iteruje pgrep/proc
. Twoja odpowiedź nie odpowiada na opublikowane pytanie. OP poprosił o metodę z podanym PID. Twoja metoda wymaga nazwy procesu.Poniższy kod działa zarówno w systemie Linux, jak i Windows i nie zależy od modułów zewnętrznych
W razie potrzeby można go łatwo ulepszyć
źródło
Powiedziałbym, że używaj PID w jakimkolwiek celu, w jakim go otrzymujesz i z wdziękiem radzisz sobie z błędami. W przeciwnym razie jest to wyścig klasyczny (PID może być ważny, gdy sprawdzisz, czy jest ważny, ale odejdź natychmiast później)
źródło