我知道asyncio在StackOverflow中有很多特性,但是尽管这里回答了很多问题,我仍然不明白如何做一些简单的事情,比如并行化2个执行阻塞代码的任务
例如,这种方法非常有效:
import asyncio
async def slow_thing():
await asyncio.sleep(2)
async def try_alpha():
print("Alpha start")
await slow_thing()
print("Alpha stop")
return "Alpha"
async def try_bravo():
print("Bravo start")
await slow_thing()
print("Bravo stop")
return "Bravo"
async def main():
futures = [
try_alpha(),
try_bravo(),
]
for response in await asyncio.gather(*futures):
print(response)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
输出正是我想要的:
Alpha start
Bravo start
*2 second wait*
Alpha stop
Bravo stop
Alpha
Bravo
但是,如果我将await syncio.sleep(2)
与time.sleep(2)
交换,输出就好像我的代码没有任何异步性一样:
Alpha start
*2 second wait*
Alpha stop
Bravo start
*2 second wait*
Bravo stop
Alpha
Bravo
问题是,在我的真实示例中,我无法控制缓慢的代码,因此我无法将其更改为使用协同程序。在某些情况下,它只是requests.get()
的一系列用法,而在另一些情况下,我使用的是kodijson
库,它做了许多我无法访问的事情
所以我想知道asyncio是否是这里的正确工具。在尝试与.gather()并行时,是否可以在异步代码中使用阻塞代码
还请注意,我(不幸地)在这一点上坚持使用Python3.6。我正在写一个Mycroft扩展,这就是他们目前所处的环境
在这里收到以评论形式提供的帮助后,我能够使用
concurrent.futures
将解决方案汇总在一起:哪些产出:
我应该注意到,官方文档不清楚您是否可以在将来通过调用}和{}值的元组,因此循环
.result()
从函数中获取返回值,或者您需要循环futures
值以获得所述结果.wait()
按返回的顺序返回{done
的值对我来说破坏了很多东西。如果你和我一样,只想同时做3件慢的事情,并从这三件事情中得到结果,那么这段代码可能适合你只有在有东西需要等待的时候,协同程序才能“并行”完成任务。例如,在上面的代码中,使用asyncio.sleep的原因是您可以在上面等待它。您只能等待为此目的而设计的特定功能。这就是为什么标准time.sleep不起作用的原因,因为你不能使用关键字wait。请求库也是如此
幸运的是,您可以使用奇妙的aiohttp库:https://docs.aiohttp.org 这将为您提供同时发出多个请求所需的确切信息
相关问题 更多 >
编程相关推荐