何时不使用asyncio有意义?

问题描述 投票:1回答:1

在什么情况下,一个线程或执行器(使用线程)超过asyncio

随着我使用Python(CPython)的经验的进步,它集中在工作中优化脚本,以批量和流程响应进行某种形式的Web服务调用。然而,经过几代脚本的构建,我发现自己想知道为什么我不会使用最新的?

请允许我在下面提供一些背景信息......

问题:从服务器A向客户端B请求N个文件,处理并保存到磁盘。

  1. 顺序 构建请求容器,发送单个请求,处理响应,重复直到完成 可能被认为是“标准/初学者”方法,因为它直观地达成了
  2. 多线程 再次构建容器,但同时发送多个请求 使用信号量限制活动连接 使用队列在工作人员和转储响应之间共享 让主线程处理响应 从本质上讲,工作人员会发生火灾并且主要在循环中运行,检查队列中的数据 保持与主要处理数据的主要问题分开
  3. 的ThreadPoolExecutor 基本上类似于解决方案2,除了少量的代码行 推理:“我希望能够尽快处理回复” 不需要显式实例化Queue和Semaphore 如果没有弄错,在as_completed()中使用Queue和Thread结构 几乎概述了here
  4. ASYNCIO 这里引入了一个严重的混淆,但概念大多被理解 与解决方案2和3不同,在单个线程上运行 除了写入磁盘之外,在实现中更接近(非常)到解决方案3 需要使用Solution 3组件通过run_in_executor()保存到磁盘

因此,我们已经达到目前的困境:为什么我不想使用asyncio进行I / O绑定工作?

异步编程是一个非常类似于OOP的概念,解决方案3的文档甚至说“可以使用线程执行异步执行”。但是,如果我可以在单个线程上实现异步执行(不包括用于阻止I / O到磁盘的其他线程),为什么我要使用解决方案1-3?

我知道,鉴于GIL,CPython多线程不是最理想的;无论如何,我认为任何人都不会再使用线程或执行器了。我已经做了很多谷歌搜索,看看我是否可以发现一篇好文章说为什么人们更愿意使用它们,但我只发现文章说为什么线程(以及后来使用线程的执行程序)是坏的:上下文切换( GIL / OS),竞争条件,资源匮乏等......

由于CPython不使用线程来利用多个核心CPU(这就是我认为的multiprocessing库),因此线程不会用于繁重的计算任务;从而将它们限制为I / O绑定操作以提高性能。但是,这并没有给我足够的理由去理解为什么线程或执行器将被用于asyncio

如果你可以在一个线程(可能是2-3)中完成所有操作,为什么要继续引入创建,管理和销毁线程的开销(显式和通过池/执行器)?

python multithreading asynchronous concurrent.futures
1个回答
0
投票

我认为多线程和asyncio之间的决定真的是你需要哪种多任务处理。如果程序中的所有内容都在您的控制之下,则asyncio / multiprocessing可能始终是正确的选择。但是,也许您想要开始一项任务,其中preemtive多任务处理是正确的选择。例如,您在第三方库中启动任务。使用线程的一个原因是该库不支持asyncio。但是,即使它支持asyncio,也许你不想相信该库可以根据需要随时控制你的任务。然后,您可以使用另一个运行该代码的asyncio事件循环启动一个新线程。

所以我认为真正的问题是:何时使用合作以及何时使用preemtive多任务处理。

© www.soinside.com 2019 - 2024. All rights reserved.