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

多线程处理大量.gz文件时卡在最后一个Future的问题排查

问题分析:ThreadPoolExecutor处理大量文件时卡在最后一个Future
def download_files_from_folder(base_url, folder_name):
    folder_url = f"{base_url}{folder_name}/"
    response = requests.get(folder_url)
    soup = BeautifulSoup(response.content, "html.parser")
    links = soup.find_all("a")
    peninsular_rain_rates = []
    east_rain_rates = []
    completed_urls = []
    with ThreadPoolExecutor(max_workers=15) as executor:
        futures = {executor.submit(process_gz_file, folder_url + link.get("href")): link.get("href") for link in links if link.get("href").endswith(".gz")}
        for future in as_completed(futures):
            peninsular, east, completed = future.result()
            peninsular_rain_rates.extend(peninsular)
            east_rain_rates.extend(east)
            completed_urls.extend(completed)
            futures.pop(future)
            print(len(futures))

这段代码用于从网站获取约8000个单文件大小约1.5MB的.gz文件链接并处理,将结果存入对应数组。使用ThreadPoolExecutor(最大工作线程数15),每完成一个Future就从字典中移除并打印剩余数量,但处理大量文件时卡在最后一个Future,处理少量文件(如50个)时运行正常,请问这是否是内存问题?

不一定是单纯的内存问题,可能是以下几种原因:

  • process_gz_file函数的潜在问题:最后一个文件的处理逻辑可能存在阻塞(比如未处理的异常、无限循环、网络重试卡住),或者该文件本身损坏/格式异常,导致线程无法返回结果。可以单独测试最后一个卡住的文件链接,验证调用process_gz_file是否能正常结束。

  • 内存占用过高引发的系统限制:8000个文件处理后,peninsular_rain_rates、east_rain_rates、completed_urls三个数组会持续扩容,若每个文件处理后生成的数据量较大,累计内存占用可能触及系统阈值,导致操作系统限制进程资源,进而让最后一个线程的执行被卡住。可以监控进程的内存使用情况,或在业务允许的前提下,分批处理并临时清理部分数据。

  • 线程资源未正常释放:虽然用with语句管理ThreadPoolExecutor,但如果process_gz_file中存在未关闭的资源(如未关闭的文件句柄、网络连接),可能导致线程无法正常退出,最后一个Future一直处于挂起状态。

  • Future字典操作的隐性问题:futures.pop(future)并非线程安全操作,不过这种情况更易引发报错而非卡住,概率相对较低。

排查建议:

  1. 打印最后一个待处理的文件名,单独调用process_gz_file验证执行情况。
  2. 监控进程内存占用,确认是否在接近系统内存上限时出现卡住现象。
  3. 在process_gz_file中添加详细日志,记录每个步骤的执行状态,定位是否有阻塞环节。
  4. 尝试降低线程池最大工作线程数(比如调到10),减少并发带来的资源竞争。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 04:32:10