You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下psutil报No such process异常,Windows正常的Python进程监控问题

解决psutil在Linux下监控进程时的NoSuchProcess异常问题

我之前也踩过这个坑!问题核心出在Linux和Windows的进程生命周期管理差异,以及psutil的异常触发逻辑上——Linux下进程终止后PID会被快速回收复用,而且当你尝试访问一个已经不存在的进程对象时,psutil会直接抛出NoSuchProcess异常;而Windows环境下因为进程资源回收机制的不同,不会立刻触发这个异常,所以你的代码在Windows能正常跑。

问题根源拆解

你当前的逻辑是直接对比进程列表,但在遍历/获取进程信息的过程中,可能刚拿到某个PID,这个进程就已经终止了,这时候去获取它的名称等属性,就会触发异常。另外,Linux的PID复用机制也可能导致误判:一个新启动的进程可能复用了刚终止进程的PID,如果只靠PID对比,会把它当成旧进程,引发逻辑错误。

具体修复方案

1. 增加异常捕获,安全获取进程信息

在获取进程的名称、启动时间等属性时,必须捕获psutil.NoSuchProcess和psutil.AccessDenied(权限问题也可能报错)异常,避免程序崩溃。

2. 优化进程标识:结合PID+启动时间

只靠PID判断进程唯一性在Linux下不可靠,加上进程的启动时间(create_time())就能准确区分不同进程,即使PID被复用也不会出错。

3. 重构对比逻辑

每次获取当前进程列表时,先安全收集所有存活进程的(PID、名称、启动时间)元组,再和历史列表对比,而不是直接操作进程对象。

示例修复代码

import psutil
import time

def get_current_processes():
    current_procs = []
    # 直接指定要获取的属性,减少异常触发概率
    for proc in psutil.process_iter(['pid', 'name', 'create_time']):
        try:
            proc_info = proc.info
            current_procs.append(
                (proc_info['pid'], proc_info['name'], proc_info['create_time'])
            )
        except (psutil.NoSuchProcess, psutil.AccessDenied):
            # 进程已终止或无权限访问,直接跳过
            continue
    return current_procs

def monitor_processes():
    historical_procs = get_current_processes()
    print("初始进程列表已加载")
    
    while True:
        current_procs = get_current_processes()
        current_set = set(current_procs)
        historical_set = set(historical_procs)
        
        # 检测新启动的进程
        new_procs = current_set - historical_set
        for proc in new_procs:
            print(f"新增进程: {proc[1]} (PID: {proc[0]})")
        
        # 检测终止的进程
        terminated_procs = historical_set - current_set
        for proc in terminated_procs:
            print(f"进程已终止: {proc[1]} (PID: {proc[0]})")
        
        historical_procs = current_procs
        time.sleep(1)

if __name__ == "__main__":
    try:
        monitor_processes()
    except KeyboardInterrupt:
        print("监控已停止")

额外说明

  • 使用psutil.process_iter()指定属性参数,比先拿到进程对象再逐个获取更高效,也减少了异常触发的概率。
  • 捕获AccessDenied异常是因为Linux下有些系统进程普通用户没有权限访问,不捕获的话也会导致程序崩溃。
  • 用集合对比差异比双重循环更高效,尤其是进程数量较多的时候。

内容的提问来源于stack exchange,提问作者neorus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:04:40