如何用create_task启动异步任务不等待完成?Asyncio循环执行问题
解决asyncio中CPU密集任务与POST任务并行执行的问题
你的代码中CPU任务和POST任务完全串行,原因是每次都要等CPU任务结束才启动POST任务,还要等POST任务结束才进入下一轮循环,根本没机会并行。要实现你预期的流程,需要做两处关键调整:
1. 修正CPU密集任务的执行方式
asyncio的事件循环是单线程的,纯CPU密集型任务会阻塞整个事件循环,导致其他协程没法运行。所以必须把CPU密集型操作放到线程池(或进程池)中执行,避免阻塞事件循环。
2. 调整任务调度逻辑
让上一轮的POST任务和下一轮的CPU任务同时启动并等待完成,这样就能实现两个任务的并行。
完整修正代码
import asyncio import requests # 同步的CPU密集型函数(替换成你的实际逻辑) def cpu_intensive_work(): result = 0 for i in range(10**7): result += i return result async def cpu_bound_task(): loop = asyncio.get_event_loop() # 将CPU密集操作交给线程池执行 result = await loop.run_in_executor(None, cpu_intensive_work) return result async def post_result_from_cpu_bound_task(res): loop = asyncio.get_event_loop() # 假设end_point和data是你定义好的变量 post_response = await loop.run_in_executor( None, requests.post, end_point, data={"computed_result": res} ) return post_response async def main(): last_post_task = None while True: # 创建当前轮的CPU任务 current_cpu_task = asyncio.create_task(cpu_bound_task()) # 并行等待:当前CPU任务 + 上一轮POST任务(如果存在) if last_post_task: await asyncio.gather(current_cpu_task, last_post_task) else: # 第一轮循环,只需等待CPU任务完成 await current_cpu_task # 获取CPU任务结果 cpu_result = current_cpu_task.result() # 创建当前轮的POST任务,交给下一轮循环等待 last_post_task = asyncio.create_task(post_result_from_cpu_bound_task(cpu_result)) asyncio.run(main())
执行逻辑说明
- 第一轮循环:启动CPU任务→等待完成→启动POST任务,此时
last_post_task指向该POST任务。 - 后续循环:启动新的CPU任务→同时等待新CPU任务和上一轮POST任务完成(两者并行执行)→获取CPU结果→启动新的POST任务,进入下一轮。
完全匹配你预期的流程:POST任务执行时,下一轮CPU任务同步运行;当CPU任务完成时,上一轮的POST任务也刚好结束,接着进入下一个循环周期。
内容的提问来源于stack exchange,提问作者humanlearning
相关产品推荐
相关产品推荐

