PID가 유효한 프로세스에 해당하는지 확인하는 방법이 있습니까? from이 아닌 다른 소스에서 pid를 얻고 있으며 해당 pid를 가진 os.getpid()
프로세스가 시스템에 존재하지 않는지 확인해야합니다.
Unix와 Windows에서 사용할 수 있어야합니다. 또한 PID가 사용되지 않는지 확인하고 있습니다.
답변
pid에 신호 0을 보내면 pid가 실행되고 있지 않으면 OSError 예외가 발생하고 그렇지 않으면 아무것도 수행하지 않습니다.
import os
def check_pid(pid):
""" Check For the existence of a unix pid. """
try:
os.kill(pid, 0)
except OSError:
return False
else:
return True
답변
psutil
모듈을 살펴보십시오 .
psutil (python 시스템 및 프로세스 유틸리티)은 Python에서 실행중인 프로세스 및 시스템 사용률 (CPU, 메모리, 디스크, 네트워크)에 대한 정보를 검색하기위한 크로스 플랫폼 라이브러리입니다 . […] 현재 Linux , Windows , OSX , FreeBSD 및 Sun Solaris , 32 비트 및 64 비트 아키텍처 모두 지원 하며 Python 버전 2.6에서 3.4까지 (Python 2.4 및 2.5 사용자는 2.1.3 버전을 사용할 수 있음) . PyPy도 작동하는 것으로 알려져 있습니다.
pid_exists()
주어진 pid를 가진 프로세스가 존재하는지 확인하는 데 사용할 수 있는 함수 가 있습니다.
예를 들면 다음과 같습니다.
import psutil
pid = 12345
if psutil.pid_exists(pid):
print("a process with pid %d exists" % pid)
else:
print("a process with pid %d does not exist" % pid)
참고로 :
답변
mluebke 코드가 100 % 정확하지 않습니다. kill ()은 또한 EPERM (액세스 거부)을 일으킬 수 있으며,이 경우 분명히 프로세스가 존재 함을 의미합니다. 이것은 작동합니다.
(Jason R. Coombs 의견에 따라 편집 됨)
import errno
import os
def pid_exists(pid):
"""Check whether pid exists in the current process table.
UNIX only.
"""
if pid < 0:
return False
if pid == 0:
# According to "man 2 kill" PID 0 refers to every process
# in the process group of the calling process.
# On certain systems 0 is a valid PID but we have no way
# to know that in a portable fashion.
raise ValueError('invalid PID 0')
try:
os.kill(pid, 0)
except OSError as err:
if err.errno == errno.ESRCH:
# ESRCH == No such process
return False
elif err.errno == errno.EPERM:
# EPERM clearly means there's a process to deny access to
return True
else:
# According to "man 2 kill" possible error values are
# (EINVAL, EPERM, ESRCH)
raise
else:
return True
pywin32, ctypes 또는 C 확장 모듈을 사용하지 않는 한 Windows에서는이 작업을 수행 할 수 없습니다. 외부 lib에 따라 괜찮다면 psutil 을 사용할 수 있습니다 .
>>> import psutil
>>> psutil.pid_exists(2353)
True
답변
프로세스에 ‘신호 0’을 보내는 것과 관련된 답변은 해당 프로세스가 테스트를 실행하는 사용자가 소유 한 경우에만 작동 합니다 . 그렇지 않으면 pid가 시스템에 존재하더라도 권한OSError
때문에 얻을 것 입니다.
이 제한을 우회하기 위해 /proc/<pid>
존재 하는지 확인할 수 있습니다.
import os
def is_running(pid):
if os.path.isdir('/proc/{}'.format(pid)):
return True
return False
이것은 분명히 리눅스 기반 시스템에만 적용됩니다.
답변
Python 3.3 이상에서는 errno 상수 대신 예외 이름을 사용할 수 있습니다. Posix 버전 :
import os
def pid_exists(pid):
if pid < 0: return False #NOTE: pid == 0 returns True
try:
os.kill(pid, 0)
except ProcessLookupError: # errno.ESRCH
return False # No such process
except PermissionError: # errno.EPERM
return True # Operation not permitted (i.e., process exists)
else:
return True # no error, we can send a signal to the process
답변
ID와 함께 실행중인 프로세스의 전체 목록을 가져 오는 Windows 별 방법을 찾으 십시오 . 그것은 다음과 같을 것입니다.
from win32com.client import GetObject
def get_proclist():
WMI = GetObject('winmgmts:')
processes = WMI.InstancesOf('Win32_Process')
return [process.Properties_('ProcessID').Value for process in processes]
그런 다음이 목록에 대해 얻은 pid를 확인할 수 있습니다. 성능 비용에 대해 잘 모르기 때문에 pid 확인을 자주 수행하려면 이것을 확인하는 것이 좋습니다.
* NIx의 경우 mluebke의 솔루션을 사용하십시오.
답변
ntrrgc를 기반으로 Windows 버전을 강화하여 프로세스 종료 코드를 확인하고 권한을 확인합니다.
def pid_exists(pid):
"""Check whether pid exists in the current process table."""
if os.name == 'posix':
import errno
if pid < 0:
return False
try:
os.kill(pid, 0)
except OSError as e:
return e.errno == errno.EPERM
else:
return True
else:
import ctypes
kernel32 = ctypes.windll.kernel32
HANDLE = ctypes.c_void_p
DWORD = ctypes.c_ulong
LPDWORD = ctypes.POINTER(DWORD)
class ExitCodeProcess(ctypes.Structure):
_fields_ = [ ('hProcess', HANDLE),
('lpExitCode', LPDWORD)]
SYNCHRONIZE = 0x100000
process = kernel32.OpenProcess(SYNCHRONIZE, 0, pid)
if not process:
return False
ec = ExitCodeProcess()
out = kernel32.GetExitCodeProcess(process, ctypes.byref(ec))
if not out:
err = kernel32.GetLastError()
if kernel32.GetLastError() == 5:
# Access is denied.
logging.warning("Access is denied to get pid info.")
kernel32.CloseHandle(process)
return False
elif bool(ec.lpExitCode):
# print ec.lpExitCode.contents
# There is an exist code, it quit
kernel32.CloseHandle(process)
return False
# No exit code, it's running.
kernel32.CloseHandle(process)
return True