内存不足致子进程被杀死时,如何处理Python subprocess异常?
子进程内存不足被杀死的异常处理方案
问题分析
你的ribodetector_cpu进程因内存不足被系统OOM(内存溢出)杀手以SIGKILL信号(编号9)终止,但当前的异常捕获逻辑未正确处理这种场景:当进程被信号终止时,subprocess.run(check=True)会抛出CalledProcessError,但该异常的returncode为负数(如-9对应SIGKILL),你的代码未针对这种情况做判断,导致 fallback 逻辑未触发。
修复后的代码
ribodetector = [ "ribodetector_cpu", "-t", str(threads), "-l", read_lenght, "-e", "rrna", "--chunk_size", "256", ] # 根据文件存在情况选择输入FASTQ if os.path.isfile(sra_filtered): ribodetector.extend(["-i", sra_filtered, "-o", sra_ribodetector_filtered]) elif os.path.isfile(sra_filtered_1): ribodetector.extend( [ "-i", sra_filtered_1, sra_filtered_2, "-o", sra_ribodetector_filtered_1, sra_ribodetector_filtered_2, ] ) command = " ".join(ribodetector) print(f"执行命令: {command}") try: # 捕获子进程输出,方便排查问题 subprocess.run(ribodetector, check=True, capture_output=True, text=True) except subprocess.CalledProcessError as e: # 判断是否为信号终止(returncode为负) if e.returncode < 0: signal_code = -e.returncode print(f"进程被信号 {signal_code} 终止,推测为内存不足") # 执行 fallback:重命名文件 if os.path.isfile(sra_filtered): os.rename(sra_filtered, sra_ribodetector_filtered) else: os.rename(sra_filtered_1, sra_ribodetector_filtered_1) os.rename(sra_filtered_2, sra_ribodetector_filtered_2) else: # 处理命令本身执行失败的情况 print(f"命令执行失败,返回码: {e.returncode}") print(f"错误信息: {e.stderr}") except OSError as e: print(f"进程启动失败: {e}")
额外优化建议
- 降低线程数(当前为40):减少并发可以降低内存占用。
- 减小
--chunk_size值:更小的处理块会降低单次内存消耗。 - 用
dmesg | grep -i kill查看系统日志,确认是否确实是OOM杀手终止了进程。
内容的提问来源于stack exchange,提问作者vini8cs
相关产品推荐
相关产品推荐

