You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

内存不足致子进程被杀死时,如何处理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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 15:23:27