我应该并行运行并收集数据一秒钟,然后在经过一段时间后返回数据。
问题是,据我所知,一个任务在另一任务之前完成,导致results
在该结果上为空。例如下面的代码:
import asyncio
import time
async def task(id, end_time):
print('Started task ', id)
results = []
while time.time() < end_time:
results.append(1)
return results
async def main():
while True:
end_time = time.time() + 1
results = await asyncio.gather(*[task(i,end_time) for i in range(2)])
print(len(results[0]), len(results[1]))
try:
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
except KeyboardInterrupt:
pass
finally:
loop.close()
返回
Started task 0
Started task 1
5580452 0
我要去哪里错了?我知道我应该以某种方式使其等待所有任务完成,然后再处理结果,但是经过一段时间摆弄不同的事情之后,我真的不知道如何实现这一目标。
您无需gather
使用不同的名称。您可以使用asyncio
的方式。
在task
协程中,删除while
并仅附加到results
一次。您将看到两个任务都将返回其输出。
问题是,当您执行while time.time()
时,您将其锁定,因为它不是异步的。因此它将运行while
循环,直到满足end_time
条件为止。
然后第二个开始,因为task
coro从未允许其间执行任何其他操作。因为两个都使用相同的end_time
,所以第二个coro将永远不会追加。
如果要异步运行while
循环,则需要为其创建附加的异步逻辑,并需要在await
函数中创建它的task
。
编辑:例如,如果您只想将其放回事件循环并允许执行其他操作,只需将await asyncio.sleep(0.1)
放入while循环中即可。
示例:
async def task(id, end_time):
print('Started task ', id)
results = []
while time.time() < end_time:
results.append(1)
await asyncio.sleep(000000000.1)
return results
改进空间:-asyncio.run(main()
负责创建事件循环-追加到列表是一项昂贵的操作,请循环尝试+= 1
,这样您的results
将以0
开头,然后打印结果,而不是其len