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

如何在磁盘剩余空间达标前持续给asyncio.gather追加下载任务?

解决方案

要实现「一个文件夹下载完成后立即启动下一个,磁盘剩余空间不足200GB时停止提交新任务但完成现有任务」的需求,可以用信号量控制并发数+逐个迭代提交任务的方式替代原有的分块批量等待逻辑,具体实现如下:

修改后的代码

import asyncio
import aiohttp
from aioshutil import disk_usage

async def bounded_download(folder, session, semaphore):
    async with semaphore:
        await download_folder(folder, session)

async def main():
    # 控制同时运行的下载任务数量(和原逻辑的每组100个保持一致)
    semaphore = asyncio.Semaphore(100)
    tasks = []
    
    async with aiohttp.ClientSession() as session:
        for folder in folders_to_download:
            # 检查磁盘剩余空间(转换为GB)
            total, used, free = await disk_usage("/media/hdd")
            free_gb = free / (10**9)
            if free_gb < 200:
                print(f"磁盘剩余空间不足200GB(当前{free_gb:.2f}GB),停止提交新任务")
                break
            
            # 提交新的下载任务,信号量会自动控制并发数
            task = asyncio.create_task(bounded_download(folder, session, semaphore))
            tasks.append(task)
        
        # 等待所有已提交的任务全部完成
        await asyncio.gather(*tasks)

关键逻辑说明

  • 并发数控制:用asyncio.Semaphore(100)限制同时运行的下载任务不超过100个,和原逻辑的分块大小一致,但无需等待整组完成——只要有一个任务结束释放信号量,下一个任务就会立即启动。
  • 磁盘空间检查时机:每次提交新任务前都检查剩余空间,一旦不足200GB就停止迭代,不再提交新任务。
  • Session复用:将ClientSession放在循环外复用,避免频繁创建销毁会话带来的性能开销。
  • 任务跟踪与收尾:用列表收集所有已启动的任务,最后通过asyncio.gather等待全部完成,确保已开始的下载任务都能正常结束。

对原代码的优化点

  1. 去掉了numpy分块的逻辑,改为逐个迭代文件夹,实现任务的无缝衔接
  2. 解决了原逻辑中「必须等整组完成才能开始下一组」的效率问题
  3. 更及时的磁盘空间检查,避免提交不必要的任务
  4. 复用ClientSession,提升整体下载效率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:17:02