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

Ubuntu下Python多进程处理DataFrame报Too Many Files Open错误

问题分析与解决方案

可能的原因

  1. 并发进程数仍超出文件描述符承载
    你假设500个进程远低于系统上限,但Ubuntu默认软文件描述符限制通常是1024,每个进程至少会占用3个描述符(stdin/stdout/stderr),加上Queue底层管道的描述符,500个进程的总描述符占用会轻松突破1024的限制。

  2. 手动管理进程与Queue导致资源泄漏
    每个Process连接全局Queue时,会创建管道的一端。即使进程结束,若未正确回收Queue的连接资源,可能残留未关闭的文件描述符。此外,你先启动所有500个进程再依次join,这段时间内所有进程的描述符都处于占用状态。

  3. 业务函数expandDates存在文件泄漏
    如果do stuff环节涉及文件操作(比如读取配置、写入临时文件),但未用with语句或手动关闭文件,会导致每个进程都残留未关闭的文件描述符,累积后触发上限。

调试步骤

  1. 检查系统文件描述符限制
    运行以下命令查看当前限制:

    # 查看软限制(当前生效的限制)
    ulimit -n
    # 查看硬限制(最大可调整到的上限)
    ulimit -Hn
    

    若软限制是1024,可临时提高:

    ulimit -n 4096
    

    永久修改需编辑/etc/security/limits.conf,添加:

    your_username soft nofile 4096
    your_username hard nofile 8192
    
  2. 实时监控进程的文件描述符
    找到主进程的PID(用ps aux | grep python),然后运行:

    lsof -p <主进程PID> | wc -l
    

    查看实时打开的文件数量,或直接看详细列表:

    lsof -p <主进程PID>
    

    重点关注TYPE=PIPE的条目(Queue的管道)和未关闭的普通文件。

  3. 排查业务函数的文件操作
    检查expandDates中的文件操作,确保所有文件都用with语句自动关闭:

    # 错误示例:未关闭文件
    f = open("data.txt", "r")
    content = f.read()
    # 正确示例:自动关闭
    with open("data.txt", "r") as f:
        content = f.read()
    

代码改进方案

最根本的解决方式是用Pool(进程池)替代手动创建Process,它会自动复用进程、控制并发数,避免大量进程同时占用资源:

import os
import pandas as pd
from multiprocessing import Pool

def expandDates(row):
    # 这里实现你的行扩展逻辑,返回扩展后的DataFrame或列表
    # 示例:生成84行数据
    expd = pd.DataFrame({"col": [row.col]*84, "date": pd.date_range(row.start_date, periods=84)})
    return expd

if __name__ == "__main__":
    # 加载原始数据
    thisData = pd.read_csv("your_data.csv")
    
    # 设置进程池大小:建议用CPU核心数的1-2倍,避免过度并发
    pool_size = os.cpu_count() * 2
    
    # 使用进程池处理,自动管理进程和结果
    with Pool(pool_size) as pool:
        # imap_unordered 支持边处理边获取结果,减少内存占用
        results = pool.imap_unordered(expandDates, thisData.itertuples())
        
        # 合并所有扩展后的结果
        final_df = pd.concat(results, ignore_index=True)
        
        # 保存最终结果
        final_df.to_csv("expanded_data.csv", index=False)

改进点说明

  • 进程池会复用固定数量的进程,不会一次性创建数百个,大幅降低文件描述符占用。
  • 无需手动管理Queue和进程的start/join/close,减少资源泄漏风险。
  • imap_unordered比map更高效,适合处理大规模数据,避免一次性加载所有结果到内存。

内容的提问来源于stack exchange,提问作者Dr. Andrew

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 23:33:24