Python进程检测案例如何查看进程运行状态

wen python案例 22

Python进程检测实战:3种核心方法精准查看进程运行状态

📖 目录导读

  1. 为什么需要Python检测进程状态?
  2. psutil库——跨平台全能选手
  3. subprocess+系统命令——轻量级原生方案
  4. os模块——基础进程信息获取
  5. 实战案例:监控Nginx进程存活状态
  6. 常见问题与解答(FAQ)

为什么需要Python检测进程状态?

在服务器运维、自动化脚本或分布式系统中,实时掌握进程运行状态是保障服务稳定性的核心环节。

Python进程检测案例如何查看进程运行状态

  • 监控Web服务器(如Nginx、Apache)是否异常退出
  • 检测Python爬虫脚本是否因内存泄漏而僵死
  • 在CI/CD流水线中验证关键进程是否按预期启动

核心检测维度包括:进程是否存在(PID)、CPU/内存占用率、运行时长、子进程状态等,传统手工ps aux | grep python效率低,而Python脚本能实现自动化告警、日志记录和动态响应。


方法一:psutil库——跨平台全能选手

psutil(Python System and Process Utilities)是目前最流行的系统监控库,支持Windows、Linux、macOS。

安装与基本用法

pip install psutil

检测单个进程是否存在

import psutil
def check_process(process_name):
    for proc in psutil.process_iter(['pid', 'name', 'status']):
        if process_name in proc.info['name']:
            return {k: v for k, v in proc.info.items()}
    return None
result = check_process('chrome')
if result:
    print(f"进程运行中: PID={result['pid']}, 状态={result['status']}")
else:
    print("进程未运行")

获取进程详细资源占用

def get_process_details(pid):
    try:
        p = psutil.Process(pid)
        return {
            'cpu_percent': p.cpu_percent(interval=0.5),
            'memory_mb': p.memory_info().rss / 1024 / 1024,
            'create_time': p.create_time(),
            'num_threads': p.num_threads()
        }
    except psutil.NoSuchProcess:
        return None
print(get_process_details(1234))

优势:统一API、无需解析命令行输出、支持获取子进程树。
注意:某些系统(如容器环境)可能限制对/proc的访问。


方法二:subprocess+系统命令——轻量级原生方案

当无法安装第三方库时,可调用系统命令,核心命令为Linux的pspgrep

使用pgrep快速查找PID

import subprocess
def find_pid_by_name(name):
    try:
        result = subprocess.run(
            ['pgrep', '-f', name],  # -f支持模糊匹配
            capture_output=True,
            text=True
        )
        if result.returncode == 0:
            return [int(pid) for pid in result.stdout.strip().split()]
        return []
    except FileNotFoundError:
        return []
pids = find_pid_by_name('python')
print(f"匹配进程PID: {pids}")

解析ps输出获取状态

def ps_process_status(pid):
    cmd = f"ps -p {pid} -o pid,stat,etime,cmd --no-headers"
    result = subprocess.run(cmd.split(), capture_output=True, text=True)
    if result.returncode == 0:
        fields = result.stdout.strip().split(maxsplit=3)
        return {
            'pid': fields[0],
            'status_code': fields[1],  # R=运行 S=睡眠 Z=僵尸
            'elapsed_time': fields[2],
            'command': fields[3]
        }
    return None

注意:跨平台性差(Windows需用tasklist),输出格式依赖系统Locale。


方法三:os模块——基础进程信息获取

os模块仅提供底层的进程管理功能,适合简单场景。

通过判断PID文件是否存在(间接检测)

import os
def is_process_running_by_pidfile(pidfile_path):
    if not os.path.exists(pidfile_path):
        return False
    with open(pidfile_path) as f:
        try:
            pid = int(f.read().strip())
        except ValueError:
            return False
    # 尝试发送空信号检查进程是否存在
    try:
        os.kill(pid, 0)
        return True
    except OSError:
        return False

直接获取当前进程状态

import os
current_pid = os.getpid()
print(f"本脚本PID: {current_pid}")
print(f"父进程PID: {os.getppid()}")

局限:无法获取非当前用户进程、CPU/内存占用等信息。


实战案例:监控Nginx进程存活状态

假设我们每分钟检测Nginx主进程是否存在,异常时发送告警。

import psutil
import time
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s')
def monitor_nginx():
    while True:
        found = False
        for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
            try:
                if 'nginx' in proc.info['name'] and 'master' in proc.info['cmdline']:
                    found = True
                    logging.info(f"Nginx正常 (PID={proc.info['pid']})")
                    break
            except (psutil.NoSuchProcess, psutil.AccessDenied):
                continue
        if not found:
            logging.error("Nginx未运行!发送告警...")
            # 在此处实现邮件/API通知逻辑
        time.sleep(60)
if __name__ == '__main__':
    monitor_nginx()

扩展思路:可结合email模块发送告警,或使用schedule实现定时检查。


常见问题与解答(FAQ)

Q1:为什么psutil获取的进程名称与ps aux显示的不一致?

A:psutil返回的是进程的name属性,而系统ps命令可能显示的是命令行中的可执行文件路径(如/usr/bin/python3 vs python3),建议使用cmdline属性精确匹配。

Q2:如何检测僵尸进程(状态Z)?

A:在psutil.Process(pid).status()返回值中,zombie状态表示为'zombie',Linux命令行中用ps aux | grep Z查看。

Q3:检测进程时遇到Permission Denied错误怎么办?

A:非root用户无法查看所有进程的信息,可尝试用sudo运行脚本,或使用psutil.Processoneshot()方法减少权限请求。

Q4:Windows下如何替代pgrep命令?

A:使用tasklist /FI "IMAGENAME eq python.exe",Python示例:

import subprocess
result = subprocess.run(['tasklist', '/FI', 'IMAGENAME eq python.exe'], capture_output=True, text=True)
if 'python.exe' in result.stdout:
    print("进程存在")

Q5:频繁轮询检测是否影响性能?

A:psutil进程迭代每秒超过1000次会影响系统,建议检测间隔≥5秒,或使用psutil.process_iter()attrs参数减少信息读取量。


延伸阅读:结合supervisorsystemd自动重启守护进程,让Python检测+恢复形成完整闭环,对于容器环境,可通过Docker SDK for Python访问容器内进程信息。

文中所用代码均可直接运行,只需确保依赖库已安装,实际生产环境请添加异常处理和日志轮转。

抱歉,评论功能暂时关闭!