python - 使用 asyncio,等待所有结果并另外取回它们的最简单方法是什么?
问题描述
for
我有一个长时间运行的函数,它被具有不同参数的循环多次调用。
我想评估该asyncio
库以轻松提高该功能的速度。
该函数返回一个特定的值,该值应该存储在for
list 中的循环级别resultList
。
我发现一些代码片段似乎满足了我“易于实现”的要求(我只需要添加@background
装饰器),但我缺少两个功能:
- 如何在
for
循环级别等待,直到函数的所有执行都执行完毕? - 如何在
for
循环级别收集函数调用的结果?
我将如何扩展此代码段?
import asyncio
import time
def background(f):
def wrapped(*args, **kwargs):
return asyncio.get_event_loop().run_in_executor(None, f, *args, **kwargs)
return wrapped
@background
def your_function(argument):
time.sleep(5)
myReturn = 'function finished for ' + str(argument)
print(myReturn)
return myReturn
if __name__ == '__main__':
resultList = []
for i in range(10):
your_function(i)
# resultList.append()
# loop = asyncio.get_event_loop().run_until_complete()
print('this should only be printed once all calls to your_function() are finished')
print("resultList=", resultList) # should contain a list of entries with 'function finished for x'
解决方案
我看到您共享的代码存在一些问题。注意:我的回答是基于您对 Jan 的评论,您提到您的功能是 I/O 受限的。
- 如果可以的话,不要使用
asyncio.get_event_loop().run_in_executor()
,asyncio.run()
在你的入口点使用并保持你的方法一直异步。(https://docs.python.org/3/library/asyncio-task.html#asyncio.run) - 您正在使用
time.sleep()
. 这是 sleep 的同步版本,不会模拟 asyncio。改为使用asyncio.sleep()
。 - 请注意,它
run_in_executor
返回一个您想要的未来对象await
。由于您在同步函数中运行代码,因此比从异步函数中运行代码更复杂。
现在,通过查看您共享的代码,没有理由将其堆栈转换为asyncio
. 如果有其他外部限制,或者这只是一个较大程序的片段,下面的解决方案可能会有点不同。否则,下面的解决方案很简单。
import asyncio
async def your_function(argument):
await asyncio.sleep(5) # note the await here (compared to time.sleep())
my_return = f"function finished for {argument}"
print(my_return)
return my_return
async def async_main():
result_list = await asyncio.gather(*(range(10))) # gather will run it all concurrently
print("this should only be printed once all calls to your_function() are finished")
print(f"result_list={result_list}", result_list) # should contain a list of entries with 'function finished for x'
if __name__ == '__main__':
asyncio.run(async_main())
推荐阅读
- matlab - 在matlab中将matlabpool转换为parpool
- python - 从优势列表中挑选出最好的元素
- node.js - 无法在 Mongoose 中填充嵌套模式引用
- python - 如何去除旧文档图像背景中的噪点
- reactjs - React-native useState 更新甚至认为它没有被调用
- javascript - 如何为文本中的每个单词添加淡入淡出动画
- javascript - 如何使用 javascript 将删除按钮添加到列表项?
- c++ - 关于 C++ 中与宏相关的某些语法的问题
- c# - 在 xaml 中设计类似 win 10 的搜索框
- firebase - 我想在我的颤振应用程序中从 firebase 数据库中获取当前用户数据