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

时间:2009-02-20 04:22:43

标签: python process pid

有没有办法检查pid是否与有效进程相对应?我从os.getpid()以外的其他来源获取pid,我需要检查机器上是否存在具有该pid的进程。

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

14 个答案:

答案 0 :(得分:142)

如果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

答案 1 :(得分:60)

查看psutil模块:

  

psutil (python系统和流程实用程序)是一个跨平台库,用于检索有关正在运行的进程系统利用率的信息(CPU, Python中的内存,磁盘,网络)。 [...]它目前支持 Linux Windows OSX FreeBSD Sun Solaris < / strong>, 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

供参考:

答案 2 :(得分:55)

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

除非使用pywin32,ctypes或C扩展模块,否则无法在Windows上执行此操作。 如果您可以使用外部库,则可以使用psutil

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

答案 3 :(得分:15)

只有当运行测试的用户拥有相关流程时,向流程发送“信号0”的答案才会生效。否则,即使系统中存在pid,您也会因权限而获得/proc/<pid>

为了绕过此限制,您可以检查import os def is_running(pid): if os.path.isdir('/proc/{}'.format(pid)): return True return False 是否存在:

{{1}}

这显然只适用于基于linux的系统。

答案 4 :(得分:6)

查看here以获取特定于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的解决方案。

答案 5 :(得分:6)

在Python 3.3+中,您可以使用异常名称而不是errno常量。 Posix version

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

答案 6 :(得分:6)

在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

答案 7 :(得分:4)

结合Giampaolo Rodolà's answer for POSIXmine for 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

答案 8 :(得分:2)

这适用于Linux,例如,如果你想检查banshee是否正在运行......(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")

答案 9 :(得分:2)

在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的文档:https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx

答案 10 :(得分:0)

以下代码可在Linux和Windows上运行,并且不依赖于外部模块

library(tidyverse)
library(tidymodels)

set.seed(55)

sample_data <- tibble(output = runif(100, min = 0, max = 80)) %>%
  mutate(a.status = round(runif(100)),
         b.status = round(runif(100)),
         c.status = ifelse(a.status + b.status < 2, 1, 0),
         d.status = ifelse(a.status + b.status + c.status < 2, 1, 0),
         a.input = a.status * output * runif(100, 1.15, 1.25),
         b.input = b.status * output * runif(100, 1.05, 1.10),
         c.input = c.status * output * runif(100, 1.3, 1.4),
         d.input = d.status * output * runif(100, 1.1, 1.2),
         input = a.input + b.input + c.input + d.input)

# From RStudio Conf
# https://conf20-intro-ml.netlify.app/materials/
fit_data <- function(formula, model, data, ...) {
  wf <- workflows::add_model(workflows::add_formula(
    workflows::workflow(), formula), model)
  fit(wf, data, ...)
}

lm_reg <- linear_reg() %>%
  set_engine("lm")
lm_fit <- fit_data(input ~ output, model = lm_reg, data = sample_data)

error_data <- sample_data %>%
  mutate(estimate = predict(lm_fit, new_data = sample_data)[[1]],
         error = (input - estimate) / input)

results <- error_data %>%
  select(a.status, b.status, c.status, d.status, error) %>%
  group_by(a.status, b.status, c.status, d.status) %>%
  summarize(error = mean(error))

可以根据需要轻松增强

  1. 其他平台
  2. 其他语言

答案 11 :(得分:0)

我发现此解决方案似乎在Windows和Linux中都可以正常工作。我用psutil检查。

gain2 = (alpha_p.'./(1-exp(-alpha_p.'.*width.'))).*((((2.*(exp((-2.*alpha_.*(1-k)-alpha_p.').*width.'))-1))./(-2.*alpha_.*(1-k)-alpha_p.'))-(((exp(-2.*alpha_.*(1-k).*width')-k)./(exp(-alpha_(1-k).*width.')-k)).*((1-exp((-alpha_.*(1-k)-alpha_p.').*width.'))./(alpha_.*(1-k)+alpha_p.'))));

答案 12 :(得分:0)

Windows 的另一个选择是通过 pywin32 包:

pid in win32process.EnumProcesses()

win32process.EnumProcesses() 返回当前正在运行的进程的 PID。

答案 13 :(得分:-2)

我会说使用PID用于获取它的任何目的并优雅地处理错误。否则,这是一场经典的比赛(当你检查它有效时,PID可能有效,但稍后就会消失)