使用asyncio模块代码仍无法异步运行,如何优化提升运行效率
问题原因
你当前的代码无法异步运行的核心原因是,async def 定义的协程函数内部没有任何可等待的(await)异步操作,所有 os 模块提供的目录遍历、属性查询方法都是同步阻塞IO,执行时会独占事件循环,导致多个协程只能串行执行,无法实现并行调度。
解决方案
因为文件系统操作本身没有原生的异步API直接适配你的场景,最简单的优化方式是将同步阻塞的计算逻辑放到异步线程池中执行,通过asyncio调度多线程并行处理多个路径的大小统计,尤其你统计的是网络共享路径,IO等待占比高,并行效果会非常明显。
修改后可正常并行运行的代码如下:
import os import asyncio # 保留原同步计算逻辑,无需修改为async def get_size(start_path='.'): total_size = 0 for dirpath, dirnames, filenames in os.walk(start_path): for f in filenames: fp = os.path.join(dirpath, f) # 跳过符号链接 if not os.path.islink(fp): total_size += os.path.getsize(fp) print(total_size) async def check_folder(folder_path1): # 把每个同步任务扔到线程池异步执行 tasks = [asyncio.to_thread(get_size, folder_path2) for folder_path2 in folder_path1] await asyncio.gather(*tasks) folder_path_deduced = [r'\\WP200\DesknetCW\Apps\App\\_config', r'\\WP101\DesknetCW\Apps\App\\_config', r'\\WD102\DesknetCW\Apps\App\\_config', r'\\WD100\DesknetCW\Apps\App\\_config'] # Python 3.7+ 可直接用asyncio.run启动事件循环 asyncio.run(check_folder(folder_path_deduced))
如果你使用的Python版本低于3.9,没有asyncio.to_thread方法,可以用loop.run_in_executor替代,对应修改部分如下:
def check_folder(folder_path1): loop = asyncio.get_event_loop() tasks = [loop.run_in_executor(None, get_size, folder_path2) for folder_path2 in folder_path1] loop.run_until_complete(asyncio.gather(*tasks))
内容的提问来源于stack exchange,提问作者Sumit Vishnoi
相关产品推荐
相关产品推荐

