psutil.NoSuchProcess错误解决及Python脚本自动重启方案咨询
问题解决方案
一、解决psutil.NoSuchProcess错误
你遇到的问题是:遍历进程ID时,刚拿到PID对应的进程可能已经退出,导致后续调用psutil.Process(pid)或进程方法时抛出异常。解决思路是给单个进程的处理逻辑添加异常捕获,同时优化进程查找方式,避免先拿PID列表再逐个创建Process对象的低效操作。
修改后的代码如下:
import psutil def find_target_process(): my_pids = [] # 直接遍历系统中的进程对象,比先拿PID列表再创建Process更高效 for proc in psutil.process_iter(['pid', 'name']): try: # 提前指定需要的字段,减少系统调用 if "solitaire.exe" in proc.info['name']: my_pids.append(proc.info['pid']) print(f"{proc.info['name']} running with pid: {proc.info['pid']}") except (psutil.NoSuchProcess, psutil.AccessDenied): # 进程已退出或无权限访问,直接跳过 continue return my_pids if __name__ == "__main__": find_target_process()
关键优化点:
- 用
psutil.process_iter()直接遍历进程对象,避免冗余的PID列表初始化操作 - 遍历前指定
['pid', 'name']字段,减少不必要的系统资源调用 - 捕获
psutil.NoSuchProcess(进程已销毁)和psutil.AccessDenied(无权限访问进程)两种常见异常,跳过出错进程继续执行
二、实现脚本自动重启
如果需要脚本在出现异常时自动重启,可以通过以下两种方式实现:
方式1:循环重试(简单易实现)
把主逻辑放到循环里,捕获所有异常,出现错误时等待一段时间后重新执行:
import psutil import time def find_target_process(): my_pids = [] for proc in psutil.process_iter(['pid', 'name']): try: if "solitaire.exe" in proc.info['name']: my_pids.append(proc.info['pid']) print(f"{proc.info['name']} running with pid: {proc.info['pid']}") except (psutil.NoSuchProcess, psutil.AccessDenied): continue return my_pids if __name__ == "__main__": while True: try: find_target_process() # 如果需要脚本执行一次后等待再检查,可添加sleep # time.sleep(10) except Exception as e: print(f"脚本出错: {str(e)},5秒后重启...") time.sleep(5) except KeyboardInterrupt: # 捕获Ctrl+C,手动终止脚本 print("脚本手动终止") break
方式2:进程替换(彻底重启脚本)
使用os.execv替换当前进程,相当于重新启动脚本,完全重置脚本状态:
import psutil import os import sys import time def find_target_process(): my_pids = [] for proc in psutil.process_iter(['pid', 'name']): try: if "solitaire.exe" in proc.info['name']: my_pids.append(proc.info['pid']) print(f"{proc.info['name']} running with pid: {proc.info['pid']}") except (psutil.NoSuchProcess, psutil.AccessDenied): continue return my_pids if __name__ == "__main__": try: find_target_process() # 按需添加执行间隔 # time.sleep(10) except Exception as e: print(f"脚本出错: {str(e)},5秒后重启...") time.sleep(5) # 重新执行当前脚本 os.execv(sys.executable, ['python'] + sys.argv) except KeyboardInterrupt: print("脚本手动终止")
注意事项:
- 两种方式都添加了
KeyboardInterrupt捕获,方便手动终止脚本,避免无限重启 - 方式1适合需要保留部分循环状态的场景;方式2会完全重置脚本,适合需要彻底重启的场景
内容的提问来源于stack exchange,提问作者Mr Diga
相关产品推荐
相关产品推荐

