Eva*_*ark 96 python pid process
有没有办法检查pid是否对应一个有效的进程?我从不同的来源获得了一个pidos.getpid(),我需要检查是否在该机器上不存在具有该pid的进程.
我需要它在Unix和Windows中可用.我还在检查PID是否未被使用.
mlu*_*bke 153
如果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
Run Code Online (Sandbox Code Playgroud)
moo*_*eep 67
看看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
Run Code Online (Sandbox Code Playgroud)
以供参考:
Gia*_*olà 58
mluebke代码不是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
Run Code Online (Sandbox Code Playgroud)
除非使用pywin32,ctypes或C扩展模块,否则不能在Windows上执行此操作.如果您可以使用外部库,则可以使用psutil:
>>> import psutil
>>> psutil.pid_exists(2353)
True
Run Code Online (Sandbox Code Playgroud)
Ome*_*gan 17
只有当运行测试的用户拥有相关进程时,涉及向进程发送"信号0"的答案才有效.否则,你会得到一个OSError因权限,即使PID系统中存在.
为了绕过此限制,您可以检查是否/proc/<pid>存在:
import os
def is_running(pid):
if os.path.isdir('/proc/{}'.format(pid)):
return True
return False
Run Code Online (Sandbox Code Playgroud)
这显然只适用于基于Linux的系统.
看这里来获取利用其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]
Run Code Online (Sandbox Code Playgroud)
然后,您可以验证此列表中的pid.我不知道性能成本,所以如果你经常要进行pid验证,你最好检查一下.
对于*NIx,只需使用mluebke的解决方案.
在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
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)