在同一个 python 项目中同时使用 asyncio 和线程是否有意义,以便代码在不同的线程中运行,其中一些 asyncio 用于获取异步活动的顺序查找代码?
或者尝试这样做是否意味着我缺少一些有关使用线程或异步的基本概念?
我不明白你在问什么(关于“顺序查找异步活动的代码”的部分),但由于没有答案,我会写一些想法。
让我们谈谈为什么我们需要 asyncio/threads。想象一下我们有一个任务要提出两个请求。
-
如果我们使用普通的单线程非异步代码,这是我们唯一的选择
是仅在完成后才对一个 url 发出请求 - for
其他:
request(url1)
request(url2)
这里的问题是我们的工作效率低下:每个函数在执行的大部分时间里什么也不做,只是等待网络结果。如果我们能够以某种方式使用 CPU 来处理第二个请求,而第一个请求则陷入网络问题并且不需要它,那就太酷了。
-
这个问题可以通过在不同线程中运行函数来解决(并且通常可以解决):
with ThreadPoolExecutor(max_workers=2) as e:
e.submit(request, url1)
e.submit(request, url2)
这样我们就能更快地得到结果。当第一个请求被网络卡住时,CPU 将能够在另一个线程中为第二个请求做一些有用的事情。
然而,这不是理想的解决方案:线程之间的切换有一些成本,执行流程比第一个示例更复杂。
应该还有更好的办法。
-
使用一个函数的空闲时间来开始执行另一个函数是 asyncio 的一般含义:
await asyncio.gather(
async_request(url1),
async_request(url2),
)
事件循环管理执行流程:当第一个协程完成某些 I/O 操作并且 CPU 可用于在其他地方执行工作时,第二个协程启动。稍后事件循环返回以继续执行第一个协程。
我们得到“并行”请求和干净易懂的代码。由于我们在单线程中实现了并行化,因此我们不需要另一个线程。
实际上,当我们使用 asyncio 线程时仍然很有用。如果我们准备好付钱给他们,他们就可以help我们可以非常快速地将同步 I/O 函数转换为异步函数:
async def async_request(url):
loop = asyncio.get_event_loop()
return (await loop.run_in_executor(None, request, url))
但同样,它是可选的,我们通常可以找到模块来异步发出请求(和其他 I/O 任务),而无需线程。
当线程在异步程序中有用时,我没有面临任何其他任务。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)