Ram*_*gil 3 python python-3.x python-asyncio
假设有一个可以进行各种数据库查询的库:
import time
def queryFoo():
time.sleep(4)
return "foo"
def queryBar():
time.sleep(4)
return "bar"
Run Code Online (Sandbox Code Playgroud)
我想同时执行这两个查询,而不必添加async到方法签名或添加装饰器。这些功能完全不应该依赖于异步。
在其中利用这些非异步功能的最佳方法是什么asyncio?
我正在寻找某种形式的东西:
#I need an 'asyncWrapper'
results = asyncio.gather(asyncWrapper(queryFoo()), asyncWrapper(queryBar()))
Run Code Online (Sandbox Code Playgroud)
预先感谢您的考虑和回应。
Ond*_* K. 10
我想你是在追求并发性,希望不要坚持使用asyncio模块本身,在这种情况下,这个小例子可能会有所帮助:
import asyncio
import time
from concurrent.futures import ThreadPoolExecutor
def queryFoo():
time.sleep(2)
return "FOO"
def queryBar():
time.sleep(4)
return "BAR"
with ThreadPoolExecutor(max_workers=2) as executor:
foo = executor.submit(queryFoo)
bar = executor.submit(queryBar)
results = [foo.result(), bar.result()]
print(results)
Run Code Online (Sandbox Code Playgroud)
它同时运行queryFoo()和queryBar()并行运行,并按照它们在分配给results.
如果某个函数在本质上是阻塞的并且不是异步的,那么在asyncio事件循环内运行它的唯一正确方法是使用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()
Run Code Online (Sandbox Code Playgroud)
它确实起作用。
但是,如果您要避免使用线程的唯一方法是重写queryFoo/ queryBar本质上是异步的。
| 归档时间: |
|
| 查看次数: |
1735 次 |
| 最近记录: |