Python案例如何查看程序进程?

wen python案例 76

本文目录导读:

Python案例如何查看程序进程?

  1. 目录导读
  2. 为什么需要查看程序进程?
  3. 基础篇:使用os模块查看当前进程信息
  4. 进阶篇:利用psutil库实现跨平台进程监控
  5. 实战案例:监控Web服务进程并自动重启
  6. 常见问题与解答(Q&A)
  7. 总结与最佳实践

Python案例:如何查看程序进程?从入门到实战,一文掌握进程监控技巧

目录导读

  1. 为什么需要查看程序进程?
  2. 基础篇:使用os模块查看当前进程信息
  3. 进阶篇:利用psutil库实现跨平台进程监控
  4. 实战案例:监控Web服务进程并自动重启
  5. 常见问题与解答(Q&A)
  6. 总结与最佳实践

为什么需要查看程序进程?

在日常Python开发或运维中,我们经常遇到以下场景:

  • 服务异常排查:某Python服务突然停止响应,需要确认进程是否还存在
  • 资源监控:需要实时统计当前运行了哪些Python脚本及其CPU/内存占用
  • 自动化运维:编写脚本定期检查特定进程是否存活,若不存活则自动重启
  • 开发调试:想了解自己的代码是否创建了多个子进程,或是否有僵尸进程残留

进程是程序的一次动态执行实例,查看进程可以帮助开发者理解程序的运行状态、资源消耗以及与其他进程的关系,掌握Python中查看进程的方法,是进阶为合格后端工程师或DevOps工程师的必备技能。


基础篇:使用os模块查看当前进程信息

Python内置的os模块提供了一些基础的进程查询功能,主要适用于当前Python进程自身

1 获取当前进程ID(PID)

import os
# 获取当前进程的PID
pid = os.getpid()
print(f"当前进程PID: {pid}")
# 获取当前进程父进程的PID
ppid = os.getppid()
print(f"父进程PID: {ppid}")

2 列出系统中所有进程(仅限Unix/Linux)

在Linux系统中,我们可以通过读取/proc文件系统来获取进程列表:

import os
def list_all_processes():
    """列出/proc下所有进程PID"""
    pids = []
    for entry in os.listdir('/proc'):
        if entry.isdigit():  # 仅处理数字命名的目录(即PID)
            pids.append(int(entry))
    return sorted(pids)
print(f"当前系统共有 {len(list_all_processes())} 个进程")

局限性os模块只能获取非常有限的进程信息(PID、PPID),无法获取进程名、CPU占用等详细数据,且跨平台性较差(Windows无法使用/proc)。


进阶篇:利用psutil库实现跨平台进程监控

psutil(Process and System Utilities)是Python生态中最强大的跨平台进程管理库,它支持Windows、Linux、macOS等主流系统。

1 安装psutil

pip install psutil

2 基础用法:获取所有进程列表

import psutil
# 获取所有进程详细信息
for proc in psutil.process_iter(['pid', 'name', 'status']):
    try:
        # 获取进程信息(dict格式)
        info = proc.info
        print(f"PID: {info['pid']}, 名称: {info['name']}, 状态: {info['status']}")
    except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
        pass

3 更详细的进程信息查询

import psutil
# 通过PID获取单个进程对象
def get_process_detail(pid):
    try:
        p = psutil.Process(pid)
        return {
            "name": p.name(),
            "exe": p.exe(),           # 可执行文件路径
            "cwd": p.cwd(),           # 工作目录
            "status": p.status(),     # 运行状态
            "cpu_percent": p.cpu_percent(interval=0.1),  # CPU使用率
            "memory_percent": p.memory_percent(),        # 内存占用百分比
            "create_time": p.create_time(),              # 创建时间戳
            "num_threads": p.num_threads(),              # 线程数
            "connections": p.connections()               # 网络连接
        }
    except psutil.NoSuchProcess:
        return None
# 示例:查看当前Python解释器进程
cur_pid = psutil.Process().pid
detail = get_process_detail(cur_pid)
if detail:
    for key, val in detail.items():
        print(f"{key}: {val}")

4 进程过滤与搜索

实际场景中,我们往往需要查找特定名称的进程,例如查找所有nginx进程:

import psutil
def find_processes_by_name(name):
    """通过进程名称查找所有匹配的进程"""
    found = []
    for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
        if proc.info['name'] == name or (proc.info['cmdline'] and name in ' '.join(proc.info['cmdline'])):
            found.append(proc.info)
    return found
# 查找Python进程
python_procs = find_processes_by_name("python3")
print(f"找到 {len(python_procs)} 个Python3进程:")
for p in python_procs[:5]:  # 只显示前5个
    print(f"PID: {p['pid']}, 命令行: {p['cmdline']}")

注意事项psutil在查询部分系统进程时可能因权限不足抛出AccessDenied异常,建议用try-except包裹。


实战案例:监控Web服务进程并自动重启

假设我们有一个名为my_web_app.py的Flask服务,现在需要编写一个Python看门狗脚本,每10秒检查一次该服务是否在运行,如果挂了则自动重启。

1 完整的监控脚本

import psutil
import subprocess
import time
import logging
# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
def is_process_running(process_name):
    """检查指定名称的进程是否在运行"""
    for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
        try:
            # 优先匹配进程名,再检查命令行中是否包含关键词
            cmdline = proc.info['cmdline']
            if cmdline and process_name in ' '.join(cmdline):
                logging.info(f"{process_name} 正在运行,PID: {proc.info['pid']}")
                return True
        except (psutil.NoSuchProcess, psutil.AccessDenied):
            continue
    return False
def restart_service(script_path):
    """重启服务"""
    logging.warning(f"进程未找到,正在重启 {script_path}...")
    try:
        # 使用nohup在后台运行,避免被终端关闭影响
        subprocess.Popen(
            ["nohup", "python3", script_path, "&"],
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL
        )
        logging.info("服务已启动")
    except Exception as e:
        logging.error(f"重启失败: {e}")
if __name__ == "__main__":
    APP_NAME = "my_web_app.py"
    APP_PATH = "/home/user/my_web_app.py"
    while True:
        if not is_process_running(APP_NAME):
            restart_service(APP_PATH)
        time.sleep(10)  # 每10秒检查一次

2 运行与测试

将此脚本保存为monitor.py,在终端运行:

python3 monitor.py &

此时即使my_web_app.py意外崩溃,监控脚本也会在10秒内重新启动它。

生产环境提示:更专业的方案是使用supervisor或systemd,但psutil方案适合嵌入式或临时监控场景。


常见问题与解答(Q&A)

Q1:为什么我用os.getpid()获取的PID和系统任务管理器看到的不一样?

Aos.getpid()获取的是当前Python进程的PID,它就是你运行的这个脚本自身的PID,如果你在交互式解释器里运行,那就是Python解释器进程;如果在脚本里运行,就是该脚本的进程,这与任务管理器显示的完全一致(除非你运行在多线程环境中)。

Q2: psutil在Windows上也能用吗?需要管理员权限吗?

A:可以,psutil完全支持Windows(包括Python for Windows),但某些操作(如终止系统进程、获取其他用户进程信息)需要管理员权限,建议在非管理员运行时用try-except捕获AccessDenied

Q3: 如何区分多个同名但不同的Python脚本进程?

A:可以通过检查cmdline(命令行参数)来区分,两个脚本都叫python3,但一个命令行是python3 a.py,另一个是python3 b.py,利用'a.py' in cmdline即可区分,推荐结合psutil.Process(pid).cmdline()方法。

Q4: 进程查看对性能有影响吗?

A:频繁调用psutil(如每秒一次)会消耗少量CPU。psutil内部会读取/proc或系统API,相对高效,但如果要监控数百个进程且间隔小于1秒,建议考虑使用系统级工具(如tophtop)或采样方式。

Q5: 如果不安装第三方库,有没有纯内置的方案查看所有进程?

A:在Linux/Mac下可以通过os.popen('ps -aux')运行系统命令并解析输出,但不够优雅且跨平台差,在Windows上只能通过wmictasklist,同样需要解析字符串,因此psutil是最推荐的跨平台方案


总结与最佳实践

  1. 明确需求:简单查看当前进程用os.getpid()即可;需要监控系统所有进程请使用psutil
  2. 警惕权限异常AccessDenied是常见问题,建议代码中做好异常处理。
  3. 避免过度CPU占用:监控进程时合理设置检查间隔(生产环境建议5-30秒)。
  4. 结合cmdline精准匹配:进程名可能重复,通过命令参数可以定位到具体脚本。
  5. 日志记录:在自动化脚本中加入日志,便于后期排查。

核心回顾: | 场景 | 推荐工具 | 优点 | |------|----------|------| | 获取当前进程PID | os.getpid() | 无需三方库,零依赖 | | 查找特定名称进程 | psutil.process_iter() | 跨平台、功能全 | | 获取内存/CPU详情 | psutil.Process() | 详细信息支持 | | 自动化进程守护 | psutil + subprocess | 可自定义逻辑 |

通过本文的案例和代码,你已经能够从零开始用Python查看程序进程、监控服务状态并实现自动恢复,掌握这些技能后,无论是开发调试还是生产运维,都能事半功倍。

延伸阅读:如果想深入了解进程管理,建议学习subprocess模块(创建进程)、signal模块(进程信号处理)以及并发编程中的进程池概念。

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