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

如何检查Python中是否存在具有给定pid的进程?,python,process,pid,Python,Process,Pid,有没有办法检查pid是否对应于有效的流程?我从不同的源获取pid,而不是从os.getpid()获取pid,我需要检查机器上是否不存在具有该pid的进程 我需要它在Unix和Windows中可用。我还在检查PID是否未使用。如果PID未运行,则向PID发送信号0将引发操作错误异常,否则不执行任何操作 import os def check_pid(pid): """ Check For the existence of a unix pid. """ try:

有没有办法检查pid是否对应于有效的流程?我从不同的源获取pid,而不是从
os.getpid()
获取pid,我需要检查机器上是否不存在具有该pid的进程


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

如果PID未运行,则向PID发送信号0将引发操作错误异常,否则不执行任何操作

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
寻找特定于windows的方法来获取运行进程及其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]
然后,您可以根据此列表验证得到的pid。我不知道性能成本,所以如果要经常进行pid验证,最好检查一下


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

我会说,无论您获得PID的目的是什么,都要使用它,并优雅地处理错误。否则,这是一场经典的比赛(当您检查PID是否有效时,PID可能有效,但稍后会消失)

mluebke代码不是100%正确;kill()还可以引发EPERM(拒绝访问),在这种情况下,这显然意味着存在一个进程。这应该是可行的:

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

请看一下模块:

psutil(python系统和进程实用程序)是一个跨平台库,用于检索python中运行进程的系统利用率(CPU、内存、磁盘、网络)的信息。[…]它目前支持LinuxWindowsOSXFreeBSDSun Solaris,都是32位和64位的体系结构,Python版本从2.6到3.4(Python 2.4和2.5的用户可以使用2.1.3版本)。PyPy也被认为是有效的

它有一个名为
pid\u 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)
供参考:

合并后,我得到了:

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
导入操作系统
如果os.name==“posix”:
def pid_存在(pid):
“”“检查当前进程表中是否存在pid。”“”
输入错误号
如果pid<0:
返回错误
尝试:
os.kill(pid,0)
除O错误为e外:
返回e.errno==errno.EPERM
其他:
返回真值
其他:
def pid_存在(pid):
导入ctypes
kernel32=ctypes.windell.kernel32
同步=0x100000
process=kernel32.OpenProcess(同步,0,pid)
如果是进程!=0:
内核32.CloseHandle(进程)
返回真值
其他:
返回错误

在Python 3.3+中,可以使用异常名称而不是errno常量:

导入操作系统
def pid_存在(pid):
如果pid<0:返回False#注意:pid==0返回True
尝试:
os.kill(pid,0)
除ProcessLookupError外:#errno.ESRCH
return False#无此过程
除许可错误外:#errno.EPERM
返回真值#不允许操作(即进程存在)
其他:
返回True#无错误,我们可以向进程发送信号

在NTRGC的基础上,我增强了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
def pid_存在(pid):
“”“检查当前进程表中是否存在pid。”“”
如果os.name==“posix”:
输入错误号
如果pid<0:
返回错误
尝试:
os.kill(pid,0)
除O错误为e外:
返回e.errno==errno.EPERM
其他:
返回真值
其他:
导入ctypes
kernel32=ctypes.windell.kernel32
句柄=ctypes.c\u void\u p
DWORD=ctypes.c_ulong
LPDWORD=ctypes.POINTER(DWORD)
类ExitCodeProcess(ctypes.Structure):
_字段\=[('hProcess',HANDLE),
('lpExitCode',LPDWORD)]
同步=0x100000
process=kernel32.OpenProcess(同步,0,pid)
如果没有,则处理:
返回错误
ec=ExitCodeProcess()
out=kernel32.GetExitCodeProcess(进程,ctypes.byref(ec))
如果没有:
err=kernel32.GetLastError()
如果kernel32.GetLastError()==5:
#访问被拒绝。
警告(“拒绝访问以获取pid信息”)
内核32.CloseHandle(进程)
返回错误
elif bool(ec.lpExitCode):
#打印ec.lpExitCode.contents
#存在一个代码,它将退出
内核32.CloseHandle(进程)
返回错误
#没有退出代码,它正在运行。
内核32.CloseHandle(进程)
返回真值

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

导入子流程
def运行_进程(进程):
“检查进程是否正在运行。是进程的名称。”
proc=subprocess.Popen([“if pgrep”+process+”>/dev/null 2>&1;然后回显“True”;否则回显“False”;fi“],stdout=subprocess.PIPE,shell=True)
(进程存在,错误)=进程通信()
返回过程存在
#使用函数
正在运行的打印过程(“女妖”)

在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的进程的句柄。如果句柄有效,则关闭进程句柄并返回True;否则,返回False。OpenProcess文档:

只有当相关进程属于运行测试的用户时,涉及向进程发送“信号0”的答案才会起作用。否则,即使pid exi
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
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
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")
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
import os

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

def pid_alive(pid:int):
    """ Check For whether a pid is alive """


    system = platform.uname().system
    if re.search('Linux', system, re.IGNORECASE):
        try:
            os.kill(pid, 0)
        except OSError:
            return False
        else:
            return True
    elif re.search('Windows', system, re.IGNORECASE):
        out = subprocess.check_output(["tasklist","/fi",f"PID eq {pid}"]).strip()
        # b'INFO: No tasks are running which match the specified criteria.'

        if re.search(b'No tasks', out, re.IGNORECASE):
            return False
        else:
            return True
    else:
        raise RuntimeError(f"unsupported system={system}")
import psutil
import subprocess
import os
p = subprocess.Popen(['python', self.evaluation_script],stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 

pid = p.pid

def __check_process_running__(self,p):
    if p is not None:
        poll = p.poll()
        if poll == None:
            return True
    return False
    
def __check_PID_running__(self,pid):
    """
        Checks if a pid is still running (UNIX works, windows we'll see)
        Inputs:
            pid - process id
        returns:
            True if running, False if not
    """
    if (platform.system() == 'Linux'):
        try:
            os.kill(pid, 0)
            if pid<0:               # In case code terminates
                return False
        except OSError:
            return False 
        else:
            return True
    elif (platform.system() == 'Windows'):
        return pid in (p.pid for p in psutil.process_iter())
pid in win32process.EnumProcesses()