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
相关产品推荐
相关产品推荐

