在MacOS上用nox运行Python测试时出现ZombieProcess异常的原因
解决nox本地运行测试时出现psutil.ZombieProcess异常的问题
问题场景
本地通过python3 -m nox运行Python测试,测试用例全部通过,但每次会话都会抛出psutil.ZombieProcess异常;相同配置在GitHub Actions上运行完全正常,无任何相关错误提示。异常触发点在自定义的进程清理逻辑中,调用proc.name()时抛出。
异常栈信息
======================================================================== 1 passed in 0.01s ======================================================================== nox > Session my_boto3_test(boto3_version='1.22.13') raised exception psutil.ZombieProcess(pid=86804, msg="PID still exists but it's a zombie") Traceback (most recent call last): File "/project_path/venv/lib/python3.9/site-packages/psutil/_psosx.py", line 343, in wrapper return fun(self, *args, **kwargs) File "/project_path/venv/lib/python3.9/site-packages/psutil/_psosx.py", line 401, in cmdline return cext.proc_cmdline(self.pid) ProcessLookupError: [Errno 3] assume no such process (originated from sysctl(KERN_PROCARGS2) -> EINVAL) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/project_path/venv/lib/python3.9/site-packages/nox/sessions.py", line 695, in execute self.func(session) File "/project_path/venv/lib/python3.9/site-packages/nox/_decorators.py", line 113, in __call__ return super().__call__(*args, **kwargs) File "/project_path/venv/lib/python3.9/site-packages/nox/_decorators.py", line 68, in __call__ return self.func(*args, **kwargs) File "/project_path/venv/lib/python3.9/site-packages/nox/_decorators.py", line 68, in __call__ return self.func(*args, **kwargs) File "/project_path/noxfile.py", line 191, in integration_tests_boto3_sqs kill_process_and_clean_outputs(full_path, "run_app", session) File "/project_path/noxfile.py", line 647, in kill_process_and_clean_outputs kill_process(process_name) File "/project_path/noxfile.py", line 657, in kill_process if proc.name() == process_name: File "/project_path/venv/lib/python3.9/site-packages/psutil/__init__.py", line 628, in name cmdline = self.cmdline() File "/project_path/venv/lib/python3.9/site-packages/psutil/__init__.py", line 681, in cmdline return self._proc.cmdline() File "/project_path/venv/lib/python3.9/site-packages/psutil/_psosx.py", line 346, in wrapper raise ZombieProcess(self.pid, self._name, self._ppid) psutil.ZombieProcess: PID still exists but it's a zombie (pid=86804) nox > Session my_boto3_test(boto3_version='1.22.13') failed.
原因分析
僵尸进程是已终止但父进程未回收其资源的进程,本地环境与GitHub Actions容器环境的进程回收机制存在差异:GitHub Actions容器中进程退出后会被快速回收,而本地系统可能存在回收延迟,导致psutil遍历进程时碰到僵尸进程并抛出异常。
解决办法
1. 捕获ZombieProcess异常,跳过僵尸进程
修改kill_process函数,在访问进程属性时捕获该异常,直接跳过无需处理的僵尸进程:
import psutil from psutil import ZombieProcess def kill_process(process_name): for proc in psutil.process_iter(['pid', 'name']): try: if proc.name() == process_name: proc.kill() except ZombieProcess: # 僵尸进程已死亡,无需处理 continue
2. 优化进程清理逻辑,避免依赖单一属性
结合进程名和命令行参数匹配进程,同时添加进程终止后的等待逻辑,减少僵尸进程产生:
import psutil from psutil import ZombieProcess, TimeoutExpired, AccessDenied def kill_process(process_name): for proc in psutil.process_iter(['pid', 'name', 'cmdline']): try: # 多维度匹配进程,降低误杀概率 if proc.name() == process_name and 'run_app' in ' '.join(proc.cmdline()): proc.terminate() # 等待进程正常终止,超时则强制杀死 proc.wait(timeout=3) except (ZombieProcess, TimeoutExpired, AccessDenied): continue
3. 升级psutil版本
旧版本psutil在处理僵尸进程时可能存在兼容性问题,升级到最新版本可修复部分场景的异常:
pip install --upgrade psutil
4. 调整nox会话的进程回收策略
在nox会话函数末尾添加显式的进程清理逻辑,确保子进程被正确回收:
@nox.session def my_boto3_test(session): # 测试逻辑 session.run("pytest", "...") # 会话结束前清理进程 kill_process("run_app")
说明
该异常属于本地环境进程回收延迟导致的非功能性错误,不影响测试结果,但会导致nox会话被标记为失败。通过上述方法可避免异常抛出,让nox会话正常结束。
内容的提问来源于stack exchange,提问作者therightstuff
相关产品推荐
相关产品推荐

