Python使用psutil.process_iter()遍历进程出现[Errno 3]错误的原因与解决
macOS下psutil遍历进程出现ProcessLookupError的原因与解决办法
错误原因
- 竞态条件导致进程状态突变:调用
psutil.process_iter()获取进程列表后,遍历到目标进程、调用proc.name()的间隙,该进程可能已被系统终止。此时psutil尝试查询已不存在的进程信息,触发错误。 - macOS特定的错误映射逻辑:在macOS系统中,psutil通过
sysctl(KERN_PROCARGS2)接口查询进程参数,若进程已终止,系统会返回EINVAL错误,psutil将其转换为ProcessLookupError异常。该异常与psutil.NoSuchProcess属于不同分支(或存在继承关系),因此原有代码仅捕获NoSuchProcess无法覆盖此场景。
解决办法
方法1:扩展异常捕获范围
直接将ProcessLookupError加入异常捕获列表,统一处理已终止/不存在的进程:
import psutil print(psutil.__version__) # 5.9.0 for proc in psutil.process_iter(): try: proc.name() except psutil.ZombieProcess: pass except (psutil.NoSuchProcess, ProcessLookupError): # 忽略已终止或不存在的进程 pass
方法2:缩小竞态窗口(更推荐)
使用psutil.process_iter()的attrs参数提前指定需要获取的属性(如name),让psutil一次性批量加载进程信息,减少后续单独查询的系统调用次数,降低进程在查询间隙消失的概率:
import psutil print(psutil.__version__) # 5.9.0 # 提前指定要获取的属性,一次性完成加载 for proc in psutil.process_iter(attrs=['name']): try: # 直接使用已缓存的属性,无需再次查询系统 proc_name = proc.info['name'] except psutil.ZombieProcess: pass except (psutil.NoSuchProcess, ProcessLookupError): pass
方法3:捕获上层OSError(备选方案)
若不想逐个列举异常类型,可捕获OSError并判断错误码,但这种方式可能误捕获其他无关系统错误,仅作为备选:
import psutil print(psutil.__version__) # 5.9.0 for proc in psutil.process_iter(): try: proc.name() except psutil.ZombieProcess: pass except OSError as e: if e.errno == 3: pass else: # 重新抛出非目标系统错误 raise
内容的提问来源于stack exchange,提问作者kuzzooroo
相关产品推荐
相关产品推荐

