Python进程检测实战:3种核心方法精准查看进程运行状态
📖 目录导读
- 为什么需要Python检测进程状态?
- psutil库——跨平台全能选手
- subprocess+系统命令——轻量级原生方案
- os模块——基础进程信息获取
- 实战案例:监控Nginx进程存活状态
- 常见问题与解答(FAQ)
为什么需要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的ps和pgrep。
使用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.Process的oneshot()方法减少权限请求。
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参数减少信息读取量。
延伸阅读:结合supervisor或systemd自动重启守护进程,让Python检测+恢复形成完整闭环,对于容器环境,可通过Docker SDK for Python访问容器内进程信息。
文中所用代码均可直接运行,只需确保依赖库已安装,实际生产环境请添加异常处理和日志轮转。