How to parallelise blocking code with asyncio
我知道 StackOverflow 中的 asyncio 功能很多,但尽管这里回答了很多问题,但我仍然不明白如何做一些简单的事情,比如并行化 2 个执行阻塞代码的任务。
例如,这很好用:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import asyncio
async def slow_thing(): async def try_alpha(): async def try_bravo(): async def main(): loop = asyncio.get_event_loop() |
输出正是我正在寻找的:
1
2 3 4 5 6 7 |
Alpha start
Bravo start *2 second wait* Alpha stop Bravo stop Alpha Bravo |
但是,如果我将
1
2 3 4 5 6 7 8 |
Alpha start
*2 second wait* Alpha stop Bravo start *2 second wait* Bravo stop Alpha Bravo |
问题是,在我的真实示例中,我无法控制那些缓慢的代码,因此我无法将其更改为使用协程。在某些情况下,它只是
所以我想知道 asyncio 是否是正确的工具。当您尝试与 .gather() 并行化时,是否可以在异步代码中使用阻塞代码?
还请注意,我(不幸地)在这方面坚持使用 Python 3.6。我正在编写一个 Mycroft 扩展程序,而这正是他们目前所坚持的环境。
在我在这里以评论的形式获得帮助后,我能够使用
汇总一个解决方案
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import concurrent.futures import time def slow_1(s): def slow_2(s): def slow_3(s): with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor: |
哪些输出:
1
2 3 4 5 6 |
2: y
3: z 1: x 1: ok 2: ok 3: ok |
我应该注意到,官方文档并不清楚你可以通过在未来调用
只有当有东西等待时,协程才能”并行”做一些事情。例如,在您上面的代码中,它与 asyncio.sleep 一起工作的原因是您可以在其上等待它。您只能等待为此目的而设计的特定功能。这就是标准 time.sleep 不起作用的原因,因为您不能使用关键字 await 。 requests 库也是如此。
幸运的是,您可以使用美妙的 aiohttp 库:https://docs.aiohttp.org
这将为您提供同时发出多个请求所需的确切信息。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/267913.html