在 Thread + Queue 或 ThreadPoolExecutor 上使用 async-await?

2024-02-14

我从未使用过async-await语法,但我经常需要发出 HTTP/S 请求并解析响应,同时等待未来的响应。为了完成这项任务,我目前使用线程池执行器 https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor无论如何异步执行调用的类;有效地,我正在实现(我相信)与使用更多行代码得到的相同结果async-await.

假设我当前的实现是异步工作的,我想知道如何async-await实现将不同于我原来使用线程和队列来管理工作人员的实现;它还使用信号量来限制工人。

该实施是在以下条件下设计的:

  • 可能有任意数量的请求
  • 活动请求总数可能为 4
  • 仅在收到响应时发送下一个请求

实施的基本流程如下:

  1. 生成请求的容器
  2. 创建监听队列
  3. 为每个请求创建一个线程并传递 URL、ListeningQueue 和 Semaphore
  4. 每个线程尝试获取信号量(限制为4个线程)
  5. 主线程继续while检查监听队列
  6. 当线程收到响应时,放入ListeningQueue并释放Semaphore
  7. 等待线程获取信号量(过程重复)
  8. 主线程处理响应,直到计数等于请求数

因为我需要限制活动线程的数量,所以我使用信号量,如果我要尝试使用async-await我必须在主线程或主线程中设计一些逻辑async def如果达到限制,则阻止发送请求。除了这个限制之外,我不知道在哪里使用async-await会更有用。是不是通过消除线程来降低开销和竞争条件机会?这是主要的好处吗?如果是这样,即使使用 ThreadPoolExecutor 进行异步调用,它也会使用线程池,从而使得async-await更好的选择?


假设我当前的实现是异步工作的,我想知道 async-await 实现与我原来使用线程和队列来管理工作人员的实现有何不同

使用以下方法实现非常相似的逻辑并不困难asyncio https://docs.python.org/3/library/asyncio.html和 async-await,它有自己的版本信号 https://docs.python.org/3/library/asyncio-sync.html#asyncio.Semaphore其使用方式大致相同。查看答案这个问题 https://stackoverflow.com/q/48483348/1600898例如,通过固定数量的任务或使用信号量来限制并行请求的数量。

至于 asyncio 相对于使用线程的等效代码的优点,有以下几个:

  • 无论活动连接的数量如何,一切都在单个线程中运行。您的程序可以扩展到大量并发任务,而不会用不合理数量的线程淹没操作系统,或者下载甚至在开始之前就必须等待线程池中的空闲槽。

  • 正如您所指出的,单线程执行不太容易受到竞争条件的影响,因为可以发生任务切换的点被清楚地标记为await,并且中间的所有内容实际上都是原子的。这样做的优点在小型线程程序中不太明显,其中执行器只是以发射和收集的方式将任务交给线程,但随着逻辑变得更加复杂并且线程开始共享更多状态(例如,由于缓存或某些原因)同步逻辑),这变得更加明显。

  • async/await 允许您轻松创建额外的独立任务,例如监视、日志记录和清理。当使用线程时,这些线程不适合执行器模型并且需要额外的线程,总是带有表明线程被滥用的设计味道。使用 asyncio,每个任务都可以像在自己的线程中运行一样,并使用await等待某件事发生(并将控制权交给其他人) - 例如基于计时器的监控任务将包含一个等待的循环asyncio.sleep() https://docs.python.org/3/library/asyncio-task.html#asyncio.sleep,但逻辑可以任意复杂。尽管代码看起来是连续的,但每个任务都是轻量级的,并且对操作系统的影响并不比分配的小对象更大。

  • async/await 支持可靠消除,线程从未这样做过,而且很可能永远不会这样做。这经常被忽视,但在 asyncio 中完全有可能cancel https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.cancel一个正在运行的任务,这会导致它从await有一个终止它的异常。取消使得实现超时、任务组和其他模式变得简单,而这些模式在使用线程时是不可能的或繁重的工作。

另一方面,async/await 的缺点是所有代码都必须是异步的。除此之外,这意味着您不能使用像 requests 这样的库,您必须切换到异步感知的替代方案,例如aiohttp https://aiohttp.readthedocs.io/en/stable/.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Thread + Queue 或 ThreadPoolExecutor 上使用 async-await? 的相关文章

  • 异步多播委托

    我最近在一个广泛使用事件的项目上做了一些工作 我需要做的事情之一是在多播委托上异步调用多个事件处理程序 我认为诀窍是对 GetInvocableList 中的每个项目调用 BeginInvoke 但似乎那里不存在 BeginInvoke 有
  • 键入的完整命令行

    我想获得输入时的完整命令行 This join sys argv 在这里不起作用 删除双引号 另外 我不想重新加入已解析和拆分的内容 有任何想法吗 你太迟了 当键入的命令到达 Python 时 您的 shell 已经发挥了它的魔力 例如 引
  • 在 C# 中创建加密随机数的最快、线程安全的方法?

    请注意 在多个线程上并行生成随机数时 加密随机数生成器不是线程安全的 使用的发电机是RNGCryptoServiceProvider它似乎重复了很长一段随机位 128 位 重现此情况的代码如下所示 缺乏使用锁来保护访问RNGCryptoSe
  • Flask 中“缺少 CSRF 令牌”,但它在模板中呈现

    问题 当我尝试登录 使用 Flask login 时 我得到Bad Request The CSRF session token is missing但令牌正在呈现 在模板中 secret key 已设置 并且我在本地运行localhost
  • Matplotlib 图例,跨列添加项目而不是向下添加项目

    对于下面的简单绘图 有没有办法让 matplotlib 填充图例 以便它从左到右填充行 而不是第一列然后第二列 gt gt gt from pylab import gt gt gt x arange 2 pi 2 pi 0 1 gt gt
  • 无法在 virtualenv 中安装 libxml2

    我有一个问题libxml2蟒蛇模块 我正在尝试将其安装在python3 虚拟环境使用以下命令 pip install libxml2 python3 但它显示以下错误 Collecting libxml2 python3 Using cac
  • django 模板 - 如何动态访问变量?

    假设我有一个具有以下上下文的 django 模板 data1 this is data1 data2 this is data2 data name data2 现在我知道了data name 假设它是 data2 是否可以用它来访问变量d
  • 用 Python 绘制直方图

    我有两个列表 x 和 y x 包含字母表 A Z Y 包含它们在文件中的频率 我尝试研究如何在直方图中绘制这些值 但在理解如何绘制它方面没有成功 n bins patches plt hist x 26 normed 1 facecolor
  • 在请求中设置端口

    我正在尝试利用cgminer使用 Python 的 API 我对利用requests图书馆 我了解如何做基本的事情requests but cgminer想要更具体一点 我想缩小 import socket import json sock
  • JavaScript Promise 不执行 .then()

    我在 JavaScript 中的 Promise 方面遇到了一些问题 我想做的是获得一个地址列表 然后对于每个地址 我需要调用地理编码 API 来获取 lat lng 然后我将继续将标记与热图一起绘制 这是我的代码 let promiseK
  • Seaborn 中没有线性拟合的散点图

    我想知道是否有办法关闭seaborn中的线性拟合lmplot或者是否有一个等效函数可以生成散点图 当然 我也可以使用 matplotlib 但是 我发现 seaborn 中的语法和美学非常吸引人 例如 我想绘制以下情节 import sea
  • 如何获取分类数据的分组条形图

    I have a big dataset with information about students And I have to build a graph of dependencies between different value
  • 如何按 pandas 中的值对系列进行分组?

    我现在有一只熊猫Series与数据类型Timestamp 我想按日期对其进行分组 并且每组中有许多行具有不同的时间 看似显而易见的方法类似于 grouped s groupby lambda x x date 然而 熊猫的groupby按索
  • 无法导入QUERY_TERMS

    我正在运行一个网站Python and Django Django filters 2 1 installed Django 2 1 installed 当我运行时 我收到以下错误 importError Could not import
  • 从迭代器外部将 StopIteration 发送到 for 循环

    有几种方法可以打破一些嵌套循环 他们是 1 使用中断 继续 for x in xrange 10 for y in xrange 10 print x y if x y gt 50 break else continue only exec
  • 如何展平解析树并存储在字符串中以进行进一步的字符串操作 python nltk

    我正在尝试从树结构中获取扁平树 如下所示 我想将整个树放在一个字符串中 就像没有检测到坏树错误一样 S NP SBJ NP DT The JJ high JJ seven day PP IN of NP DT the CD 400 NNS
  • Django 将 JSON 数据传递给静态 getJSON/Javascript

    我正在尝试从 models py 中获取数据并将其序列化为views py 中的 JSON 对象 模型 py class Platform models Model platformtype models CharField max len
  • 使用 MPI 的 Allreduce 对 Python 对象求和

    我正在使用使用 Python 中的字典和计数器构建的稀疏张量数组操作 我想让并行使用这个数组操作成为可能 最重要的是 我最终在每个节点上都有计数器 我想使用 MPI Allreduce 或另一个不错的解决方案 将其添加在一起 例如 使用计数
  • 使用 pandas 单元格中列表的长度选择行[重复]

    这个问题在这里已经有答案了 我有一张表 df a b c 1 x y x 2 x z c d 3 x t e f g 只是想知道如何使用 c 列的长度选择行 such as df loc len df c gt 1 我知道这是不对的 正确的
  • 为boost python编译的.so找不到模块

    我正在尝试将 C 代码包装到 python 中 只需一个类即可导出两个函数 我编译为map so 当我尝试时import map得到像噪音一样的错误 Traceback most recent call last File

随机推荐

  • 如何覆盖 Vue 组件中的作用域样式?

    让我们保存一下我有一个 Vue我从 Github 上的某个地方获取的组件 我们将其称为 CompB 并为蓝色标头添加一个 CSS 规则集 CompB Vue 我不拥有的依赖项 可能是从 Github 中提取的
  • 默认情况下,SQLite 真的不保留外键约束的数据完整性吗?

    较新版本的 SQLite支持外键约束 https stackoverflow com questions 3297363 implement use foreign keys in sqlite 可以定义 CREATE TABLE MAST
  • 使用 jquery 进行文本框验证

    我是 JQuery 新手 我想使用 jquery 对四个文本框进行验证 我已经完成的编码
  • onClick 函数“this”返回窗口对象

    我的 JavaScript 应用程序遇到了一个令人头疼的问题 如果我写一个这样的元素 li li 我得到 李 但是如果我这样做 li li 其中 foo 是 function foo alert this tagName 我得到 未定义 我
  • 在Python 2.7中编码时如何处理Linux上带空格的路径?

    我有一个 python 脚本 用于处理 Linux Mint 上目录中的文件 部分代码如下 path to dir home user Im a folder with libs to install if os path isdir pa
  • AngularJS http 返回值

    我想在 AngularJS 中编写一个返回值的函数 实际上它是一个字符串 该值是由 http 请求返回的 但异步让我发疯 我的第一次尝试是 this readParameter function key http method GET ur
  • Xamarin Forms - Prism - OnNavigedTo 调用两次

    因此 我已经使用 prism 开发了一个应用程序 2 个月 现在我意识到当我从 MasterDetailPage 中选择一个项目时 OnNavigedTo 方法被调用了两次 我不知道为什么会发生这种情况 我确信我错过了一些东西 但我大约需要
  • 实体框架核心代码优先:多对多关系的级联删除

    我正在使用 Entity Framework Core 版本 EntityFramework Core 7 0 0 rc1 final 由 SQL Server 2012 Express DB 支持 我需要建立一个多对多关系模型Person
  • 5秒后自动滚动页面到div

    我是 javascript 新手 现在我正在尝试这样做 如标题所示 我有一个页面 顶部有一个 div 与包含视频的页面一样大 后面是几个部分 例如这 div style height 100 width 100 div section st
  • IE9 现在会支持 WebSocket 吗?

    这个问题很简单 老话题是here https stackoverflow com questions 3377096 will ie9 support webgl and or websockets 自从 IE9 将于 2011 年 3 月
  • Verilog 中的“net”代表什么?

    我刚刚开始学习Verilog 据我了解 Verilog有net数据类型 什么是net代表 网络就是这样一种数据类型 您不使用它来存储值 它们代表物理连接 您可以将线路视为一种网络数据类型 你可以去网上看看更多here http www ee
  • 使用 KernelClient API 在 ipython 内核中执行代码

    我有一个现有的 ipython 内核 带有一个通信文件 path comm file json 我想使用内核客户端 API 执行该内核中的代码 实际上我并不挑剔 任何方法都可以 我明白这是从 jupyter 做事情的最好方法文档 https
  • 从事神经网络项目[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 神经网络是否需要仅采用二进制训练集
  • Trello 如何如此快速地显示历史记录?

    Trello 显示自论坛成立以来任何用户所做的一切的历史日志 同样 如果您单击特定的卡片 它会显示任何人与该卡片相关的任何操作的历史记录 跟踪无限期保留的每个更改 添加 删除必须收集大量数据 并且还可能成为写入历史记录日志的瓶颈 假设它立即
  • 如何在提交之前做一些事情?

    我有一个表单 其中有一个提交表单的按钮 我需要在提交发生之前做一些事情 我尝试做onClick在该按钮上 但它发生在提交之后 我无法共享代码 但一般来说 我应该在 jQuery 或 JS 中做什么来处理这个问题 如果您有这样的表格
  • c - strcmp 对于相等的字符串不返回 0

    因此 我尝试广泛寻找解决方案 但只能真正找到其中一个字符串缺少新行或空字节的帖子 我相当确定这里的情况并非如此 我正在使用以下函数将单词与包含单词列表的文件进行比较 其中每行一个单词 函数中的字典 这是代码 int isWord char
  • 在 DataGridView 的列中搜索值

    我希望用户能够在 DataGridView dgv 的列中搜索数字 dgv 可以保持许多记录 每条记录都有一个项目编号 因此 我希望用户能够在 项目编号 列中搜索项目编号 我的列是 ProjectID 不可见 图片 无标题文本 项目编号 项
  • 如何在标准输出中禁用 spring boot 徽标?

    有没有办法禁用可爱但非常明显的 ASCII Spring boot 徽标 Spring Boot v1 1 8 RELEASE 每次运行 Spring Boot 应用程序时都会
  • MySQL中使用clearDB自动加1

    我正在使用带有clearDB 的Windows Azure 当前数据库自增值为10 我希望它为1 我尝试在 PHPMyAdmin 中运行这些命令 1 set global auto increment increment 1 set glo
  • 在 Thread + Queue 或 ThreadPoolExecutor 上使用 async-await?

    我从未使用过async await语法 但我经常需要发出 HTTP S 请求并解析响应 同时等待未来的响应 为了完成这项任务 我目前使用线程池执行器 https docs python org 3 library concurrent fu