在 Python 中将 asyncio 用于非异步函数? [英] Using asyncio for Non-async Functions in Python?
问题描述
假设有一个库可以进行各种数据库查询:
Suppose there is a library that makes various database queries:
import time
def queryFoo():
time.sleep(4)
return "foo"
def queryBar():
time.sleep(4)
return "bar"
我想同时执行这 2 个查询,而不必将 async
添加到方法签名或添加装饰器.这些函数根本不应该依赖于 asyncio.
I want to execute those 2 queries concurrently without having to add async
to the method signature or adding a decorator. These functions should not depend on asyncio at all.
在 asyncio
中利用这些非异步函数的最佳方式是什么?
What is the best way to utilize those non-async functions within asyncio
?
我正在寻找某种形式的东西:
I am looking for something of the form:
#I need an 'asyncWrapper'
results = asyncio.gather(asyncWrapper(queryFoo()), asyncWrapper(queryBar()))
预先感谢您的考虑和回复.
Thank you in advance for your consideration and response.
推荐答案
如果某些函数本质上是阻塞的而不是异步的,那么在 asyncio
事件循环中运行它的唯一正确方法是在内部运行它使用 run_in_executor 的线程:
If some function is blocking and not async by nature, only proper way to run it inside asyncio
event loop is to run it inside thread using run_in_executor:
# Our example blocking functions
import time
def queryFoo():
time.sleep(3)
return 'foo'
def queryBar():
time.sleep(3)
return 'bar'
# Run them using asyncio
import asyncio
from concurrent.futures import ThreadPoolExecutor
_executor = ThreadPoolExecutor(10)
async def in_thread(func):
loop = asyncio.get_event_loop()
return await loop.run_in_executor(_executor, func)
async def main():
results = await asyncio.gather(
in_thread(queryFoo),
in_thread(queryBar),
)
print(results)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main())
finally:
loop.run_until_complete(loop.shutdown_asyncgens())
loop.close()
它确实起作用.
如果你想避免使用线程唯一的方法 - 是重写 queryFoo
/queryBar
本质上是异步的.
If you however want to avoid using threads only way to do it - is to rewrite queryFoo
/queryBar
to be async by nature.
这篇关于在 Python 中将 asyncio 用于非异步函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!