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

Linux环境下Python multiprocessing任务完成后进程仍存活求助

问题成因
  1. 你的代码中executor.map返回的是惰性迭代器,你把遍历迭代器的save_results_to_csv(results)逻辑放在了ProcessPoolExecutor的with上下文块之外。虽然with块退出时默认会调用shutdown(wait=True)等待所有任务执行完成,但3.8版本中存在任务结果未完全消费时,子进程回收逻辑异常的已知缺陷。
  2. Python 3.8版本的concurrent.futures.ProcessPoolExecutor本身存在多个子进程回收相关的bug,部分场景下即使所有任务执行完成,子进程也不会自动退出,变成闲置存活进程。
  3. 你用到的BioPython的Align模块底层是C扩展实现,部分版本可能存在自定义信号处理逻辑,会拦截主进程发给子进程的退出信号,导致子进程无法正常终止。
修复方案
  • 调整迭代器遍历位置,将结果消费逻辑移入with上下文块内,确保所有任务结果被完全接收后再退出executor上下文,同时可增加手动清理残留进程的逻辑,修改compute_using_multi_processing函数代码如下:
def compute_using_multi_processing(list_comb_ids, dict_ids_seqs):
    import datetime
    start = time.perf_counter()

    with concurrent.futures.ProcessPoolExecutor(max_workers=nb_cpu) as executor:
        results = executor.map(help_fun_job,
                               [((pair_ids[0], dict_ids_seqs[pair_ids[0]]), (pair_ids[1], dict_ids_seqs[pair_ids[1]]))
                                for pair_ids in list_comb_ids])
        # 结果消费逻辑移入with块内部,所有结果处理完成后再退出上下文
        save_results_to_csv(results)

    finish = time.perf_counter()

    proccessing_time = str(datetime.timedelta(seconds=round(finish - start, 2)))
    print(f' Processing time Finished in {proccessing_time} hh:mm:ss')
    
    # 手动清理所有残留子进程
    current_process = psutil.Process()
    for child in current_process.children(recursive=False):
        try:
            child.terminate()
            child.wait(timeout=3)
        except (psutil.NoSuchProcess, psutil.TimeoutExpired):
            child.kill()
  • 优先升级Python版本到3.9及以上,该版本修复了ProcessPoolExecutor绝大多数的进程泄漏问题,无需额外修改代码即可解决子进程不退出的问题。
  • 如果必须保留Python 3.8环境,上述代码中的手动清理子进程逻辑可以保证任务完成后没有闲置进程残留。
  • 升级BioPython到最新稳定版本,修复底层C扩展的信号处理异常问题。

内容的提问来源于stack exchange,提问作者ibra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 22:18:03