Asyncio任务未并发执行:异步CLI取数与HTTP上报问题咨询
问题分析与解决
你的代码看似用了asyncio框架,但实际还是同步执行,核心问题在于execute函数里的两个方法get_json_data_from_cli()和post_data_to_http_endpoint()都是同步阻塞操作——它们会一直占用当前线程,完全不给asyncio事件循环切换到其他任务的机会。
asyncio的await关键字只有在遇到真正的异步IO操作(比如异步子进程调用、异步HTTP请求、asyncio.sleep()等)时,才会把控制权交还给事件循环,让其他任务并行执行。你的代码里没有这类异步操作,自然没法实现并发。
具体改造步骤
1. 异步执行CLI命令
如果get_json_data_from_cli()是调用外部CLI工具,别用subprocess.run()这种同步方法,改用asyncio.create_subprocess_exec()/asyncio.create_subprocess_shell()来异步执行:
async def get_json_data_from_cli(self): # 异步启动CLI进程,捕获输出 proc = await asyncio.create_subprocess_exec( "你的CLI命令", self.project, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE ) stdout, stderr = await proc.communicate() # 解析输出为JSON self.json_data = json.loads(stdout.decode("utf-8"))
2. 异步发送HTTP请求
如果post_data_to_http_endpoint()用的是requests这类同步HTTP库,换成异步库aiohttp:
async def post_data_to_http_endpoint(self): async with aiohttp.ClientSession() as session: async with session.post( "你的HTTP上报端点", json=self.json_data ) as resp: # 按需处理响应 await resp.text()
3. 让execute函数真正异步
修改execute函数,确保调用异步方法时加上await:
async def execute(project): nb_object = Notebooks(project) await nb_object.get_json_data_from_cli() await nb_object.post_data_to_http_endpoint()
关键提醒
- 异步框架的核心是避免同步阻塞,只要代码里存在同步阻塞操作,整个事件循环就会被卡死,所有任务都会变成串行执行。
asyncio.gather()确实能并发运行多个任务,但前提是每个任务内部没有同步阻塞逻辑。
内容的提问来源于stack exchange,提问作者ddNip
相关产品推荐
相关产品推荐

