如何检查在Python中是否存在具有给定pid的进程?

有没有办法检查一下,如果一个PID对应于一个有效的过程? 我得到一个不同于os.getpid()来源的pid,我需要检查是否有一个与该pid进程不存在的机器上。

我需要它在Unix和Windows中可用。 我也在检查是否PID未被使用。

发送信号0给一个PID将引发一个OSErrorexception,如果该PID没有运行,否则不做任何事情。

 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 

密码不是100%正确的; kill()也可以提高EPERM(访问被拒绝),这种情况显然意味着一个进程存在。 这应该是工作:

(根据Jason R. Coombs的评论进行编辑)

 import errno import os import sys 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上执行此操作。 如果您可以使用psutil,则可以使用外部库:

 >>> import psutil >>> psutil.pid_exists(2353) True 

看看psutil模块:

psutil (python系统和进程工具)是一个跨平台的库,用于检索Python中正在运行的进程系统利用率 (CPU,内存,磁盘,networking)的信息。 它目前支持Linux版本WindowsOSXFreeBSDSun Solaris32位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 

以供参考:

在这里寻找特定于窗口的方式,用它们的ID来获取正在运行的进程的完整列表。 这将是类似的东西

 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] 

然后你可以validation你对这个列表的pid。 我不知道性能成本,所以你最好检查一下,如果你打算经常进行pidvalidation。

对于* NIx,只需使用mluebke的解决scheme。

在Python 3.3+中,可以使用exception名称而不是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 (ie, process exists) else: return True # no error, we can send a signal to the process 

结合GiampaoloRodolà的POSIX和我的Windows 的答案我得到这个:

 import os if os.name == 'posix': def pid_exists(pid): """Check whether pid exists in the current process table.""" 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: def pid_exists(pid): import ctypes kernel32 = ctypes.windll.kernel32 SYNCHRONIZE = 0x100000 process = kernel32.OpenProcess(SYNCHRONIZE, 0, pid) if process != 0: kernel32.CloseHandle(process) return True else: return False 

build立在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 

涉及向进程发送“信号0”的答案只有在所讨论的进程由运行testing的用户拥有的情况下才有效 。 否则,即使系统中存在pid,您也会因为权限而获得OSError

为了绕过这个限制,你可以检查/proc/<pid>存在:

 import os def is_running(pid): if os.path.isdir('/proc/{}'.format(pid)): return True return False 

在Windows中,你可以这样做:

 import ctypes PROCESS_QUERY_INFROMATION = 0x1000 def checkPid(pid): processHandle = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_INFROMATION, 0,pid) if processHandle == 0: return False else: ctypes.windll.kernel32.CloseHandle(processHandle) return True 

首先,在这个代码中,你可以尝试使用pid给出一个处理句柄。 如果句柄有效,则closures句柄进行处理并返回True; 否则,你返回False。 OpenProcess的文档: https : //msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx

这将适用于Linux,例如,如果你想检查女妖是否正在运行…(banshee是一个音乐播放器)

 import subprocess def running_process(process): "check if process is running. < process > is the name of the process." proc = subprocess.Popen(["if pgrep " + process + " >/dev/null 2>&1; then echo 'True'; else echo 'False'; fi"], stdout=subprocess.PIPE, shell=True) (Process_Existance, err) = proc.communicate() return Process_Existance # use the function print running_process("banshee") 

我会说,无论您获得它的目的,使用PID和优雅地处理错误。 否则,这是一个经典的比赛(当你检查它的有效性时,PID可能是有效的,但是稍后离开)