python协程—asyncio模块

2023-11-01

为什么使用协程?

当多线程或者多进程足够多时,实际上并不能解决性能的瓶颈问题,也就是多线程和多进程对小规模的请求可以提高效率,过多的请求实际上会降低服务资源响应效率,因此协程是更好的解决文案。

什么是协程?

当一个程序遇到阻塞时,如果将这个程序挂起,然后将它的cpu权限拿出来去执行我们的其他程序,执行完后再回过头来执行这些挂起的程序,此时所有非阻塞操作已经执行完毕,最后在一起执行阻塞程序,是不是相当于做了异步。

因此,协程的作用就是检测阻塞的程序,在单进程和单线程的情况下实现异步,相比多线程和多进程效率更高。

asyncio协程模块(python3.5以上)

协程的代码基本构成

  • 特殊函数

    • 在普通函数前添加一个async关键字,则该函数就变成一个特殊的函数
    • 特殊函数的特殊之处是什么?
      • 1.特殊函数被调用后,函数内部的程序语句(函数体)没有被立即执行
      • 2.特殊函数被调用后,会返回一个协程对象
  • 协程:

    • 调用特殊函数即创建一个协程对象。
    • 因此,协程对象 = 特殊的函数 = 函数体(一组指定形式的操作)
  • 任务:

    • 任务对象就是一个高级的协程对象,即任务对象可以绑定一个回调函数
    • 任务对象 = 协程对象 == 函数体(一组指定形式的操作)
  • 事件循环:

    • 事件循环对象,,可以将其当做是一个容器,该容器是用来装载任务对象的。创建好了一个或多个任务对象后,将任务对象装载到事件循环中,启动事件循环对象,则其内部装载的任务对象对应的相关操作就会被立即执行。
import asyncio
import time
# 创建特殊函数,一般将有阻塞操作设置特殊函数,在普通函数前加关键字async
async def get_request(url):
    print('正在请求的网址是:',url)
    time.sleep(2)
    print('请求网址结束!')
    return 123

# 自定义一个回调函数(一般来做数据解析),给任务对象使用:必须有一个参数,用来获取特殊函数的返回值
def t_callback(t):
    #参数t就是任务对象
    data = t.result() #result()函数就可以返回特殊函数内部的返回值
    print('获取到特殊函数的返回值为:',data)

# 创建协程对象
c = get_request('www.123.com')

# 创建任务对象
task = asyncio.ensure_future(c)

# 任务对象添加回调函数,事件对象启用的时候,特殊函数和回调函数按顺序执行
task.add_done_callback(t_callback)

#创建事件循环对象
loop = asyncio.get_event_loop()
loop.run_until_complete(task)

多任务的协程

特殊函数内部,不可以出现不支持异步模块的代码,否则会中断整个异步效果,例如sleep,requests,可以通过执行程序来判断。具体操作如下:

添加多个任务需要使用:wait()函数,其他代码省略,看最后一步
'''
特殊函数
回调函数
协程对象
'''

tasks = []
for url in urls:
    c = get_request(url)
    task = asyncio.ensure_future(c)
    task.add_done_callback(parse)
    tasks.append(task)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
await关键字:挂起发生阻塞操作的任务对象。在任务对象表示的操作中,凡是阻塞操作的前面都必须加上await关键字进行修饰,但不是所有阻塞操作都可以加await,需要添加支持协程的阻塞操作,await才会生效

async def get_request(url):
    print('正在请求:',url)
    await asyncio.sleep(2)
    print('请求结束:',url)

完整代码

# 特殊函数先写出基本的网络请求框架,然后在每个with前面加async,每个阻塞操作前await,便于看懂和记忆
# 使用with是为了关闭协程,避免浪费资源
import asyncio
import time
from lxml import etree
import aiohttp
start = time.time()
urls = [
    'https://www.baidu.com',
    'https://www.baidu.com',
    'https://www.baidu.com'
]
#该任务是用来对指定url发起请求,获取响应数据
async def get_request(url):
    # requests是不支持异步的模块,所以加了await也没用
    # response = await requests.get(url=url)

    #aiohttp是支持协程的网络请求,跟requests类似,创建请求对象(aiohttp_requests)
    async with aiohttp.ClientSession() as aiohttp_requests:
        #get请求,常用参数:url,headers,params,proxy
        #post请求,常用参数:url,headers,data,proxy
        #aiohttp处理代理的参数和requests不一样(注意),此处处理代理使用proxy='http://ip:port'
        async with await aiohttp_requests.get(url=url) as response:
            page_text = await response.text()
            #text():获取字符串形式的响应数据
            #read():获取二进制形式的响应数据
            await asyncio.sleep(2)
            return page_text
def call_back(t):#回调函数专门用于数据解析
    #获取任务对象请求到的页面源码数据
    page_text = t.result()
    tree = etree.HTML(page_text)
    a = tree.xpath('//a[1]/@href')
    print(a)

tasks = []
for url in urls:
    c = get_request(url)
    task = asyncio.ensure_future(c)
    task.add_done_callback(call_back)
    tasks.append(task)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

print('总耗时:',time.time()-start)

uvloop加速

uvloop基于libuv,libuv是一个使用C语言实现的高性能异步I/O库,uvloop用来代替asyncio默认事件循环,可以进一步加快异步I/O操作的速度。 

import uvloop
loop = asyncio.get_event_loop()
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) # 在启用事件前加这一行代码即可
loop.run_until_complete(asyncio.wait(tasks))

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

python协程—asyncio模块 的相关文章

  • Python - 比较同一字典中的值

    我有一本字典 d Trump MAGA FollowTheMoney Clinton dems Clinton Stein FollowTheMoney Atlanta 我想删除字符串列表中的重复字符串 该字符串是键的值 对于这个例子 期望
  • 如何在 Matplotlib 饼图周围绘制箭头以将每个标签指向圆圈中各自的部分?

    我一直在用 Matplotlib 绘制一些图表 我有一个饼图 想要在图表周围绘制箭头 使每个标签都指向图表 我有一个例子 这是我当前的代码 import matplotlib pyplot as plt plt rcParams font
  • 如何在 __init__ 中使用await设置类属性

    我如何定义一个类await在构造函数或类体中 例如我想要的 import asyncio some code class Foo object async def init self settings self settings setti
  • python multiprocessing 设置生成进程等待

    是否可以生成一些进程并将生成进程设置为等待生成的进程完成 下面是我用过的一个例子 import multiprocessing import time import sys def daemon p multiprocessing curr
  • 在 Django Admin 中调整字段大小

    在管理上添加或编辑条目时 Django 倾向于填充水平空间 但在某些情况下 当编辑 8 个字符宽的日期字段或 6 或 8 个字符的 CharField 时 这确实是一种空间浪费 字符宽 然后编辑框最多可容纳 15 或 20 个字符 我如何告
  • 为什么 web2py 在启动时崩溃?

    我正在尝试让 web2py 在 Ubuntu 机器上运行 所有文档似乎都表明要在 nix 系统上运行它 您需要下载源代码并执行以下操作 蟒蛇 web2py py 我抓住了source http www web2py com examples
  • Python 内置的 super() 是否违反了 DRY?

    显然这是有原因的 但我没有足够的经验来认识到这一点 这是Python中给出的例子docs http docs python org 2 library functions html super class C B def method se
  • 从 Powershell 脚本安装 Python

    当以管理员身份从 PowerShell 命令行运行以下命令时 可以在 Windows 11 上成功安装 Python c temp python 3 11 4 amd64 exe quiet InstallAllUsers 0 Instal
  • 尽管我已在 python ctypes 中设置了信号处理程序,但并未调用它

    我尝试过使用 sigaction 和 ctypes 设置信号处理程序 我知道它可以与python中的信号模块一起使用 但我想尝试学习 当我向该进程发送 SIGTERM 时 但它没有调用我设置的处理程序 只打印 终止 为什么它不调用处理程序
  • Python - 如何确定解析的 XML 元素的层次结构级别?

    我正在尝试使用 Python 解析 XML 文件中具有特定标记的元素并生成输出 excel 文档 该文档将包含元素并保留其层次结构 我的问题是我无法弄清楚每个元素 解析器在其上迭代 的嵌套深度 XML 示例摘录 3 个元素 它们可以任意嵌套
  • Django REST Framework - CurrentUserDefault 使用

    我正在尝试使用CurrentUserDefault一个序列化器的类 user serializers HiddenField default serializers CurrentUserDefault 文档说 为了使用它 请求 必须作为
  • Protobuf 如何编码 oneof 消息结构

    对于这个 python 程序 在编码时运行 protobuf 编码会给出以下输出 0a 10 08 7f8a 0104 08 02 10 0392 0104 08 02 10 03 18 01 我不明白的是为什么8a后面有一个01 为什么9
  • 在 Google App Engine 中,如何避免创建具有相同属性的重复实体?

    我正在尝试添加一个事务 以避免创建具有相同属性的两个实体 在我的应用程序中 每次看到新的 Google 用户登录时 我都会创建一个新的播放器 当新的 Google 用户在几毫秒内进行多个 json 调用时 我当前的实现偶尔会创建重复的播放器
  • PySpark groupByKey 返回 pyspark.resultiterable.ResultIterable

    我试图找出为什么我的 groupByKey 返回以下内容 0
  • Python:Goslate 翻译请求返回“503:服务不可用”[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我们不允许提出寻求书籍 工具 软件库等推荐的问题 您可以编辑问题 以便用事实和引文来回答 这个问题似乎不是关于主要由程序员使用的特定编程问
  • 如何以正确的方式为独立的Python应用程序制作setup.py?

    我读过几个类似的主题 但还没有成功 我觉得我错过或误解了一些基本的事情 这就是我失败的原因 我有一个用 python 编写的 应用程序 我想在标准 setup py 的帮助下进行部署 由于功能复杂 它由不同的 python 模块组成 但单独
  • 重新分配唯一值 - pandas DataFrame

    我在尝试着assign unique值在pandas df给特定的个人 For the df below Area and Place 会一起弥补unique不同的价值观jobs 这些值将分配给个人 总体目标是使用尽可能少的个人 诀窍在于这
  • 制作一份 Python 文档的 PDF 文件

    Python 官方网站提供 PDF 文档下载 但它们是按章节分隔的 我下载了源代码并构建了 PDF 文档 这些文档也是单独的 PDF 我怎么能够从源代码中的 Makefile 构建一个 PDF 文件 我认为这样阅读起来会更方便 如果连接单独
  • 在virtualenv中下载sqlite3

    我正在尝试使用命令创建应用程序python3 manage py startapp webapp但我收到一条错误消息 django core exceptions ImproperlyConfigured 加载时出错 pysqlite2 或
  • NLTK:查找单词大小为 2k 的上下文

    我有一个语料库 我有一个词 对于语料库中该单词的每次出现 我想获取一个包含该单词之前的 k 个单词和该单词之后的 k 个单词的列表 我在算法上做得很好 见下文 但我想知道 NLTK 是否提供了一些我错过的功能来满足我的需求 def size

随机推荐

  • MapReduce(一):FileInputFormat源码解析

    来源 https www bilibili com video av36033875 from search seid 12700632591522714293 FileInputFormat切片机制 1 job提交流程源码详解 主要代码流
  • 虚拟内存有什么用

    虚拟内存是什么 虚拟内存别称虚拟存储器 Virtual Memory 电脑中所运行的程序均需经由内存执行 若执行的程序占用内存很大或很多 则会导致内存消耗殆尽 为解决该问题 Windows中运用了虚拟内存技术 即匀出一部分硬盘空间来充当内存
  • 【threejs效果:模型炸开】以钢铁侠obj模型为例

    1 效果如下 2 基本原理 首先加载一个obj模型 然后遍历obj模型的所有children mesh 按一定比例改变每个子mesh的中心点位置即可 爆炸代码 function modelExplode num 模型世界中心 var mod
  • 游戏资源贴

    转载自 http www gamedev net community forums topic asp topic id 324643 Ok so the point of this thread is simple to list as
  • Linux 6.6 中的 SELinux 删除了 NSA 的引用

    导读 Security Enhanced Linux SELinux 二十年来一直是主线内核的一部分 它提供了一个实现访问控制安全策略的模块 现在广泛用于增强生产 Linux 服务器和其他系统的安全性 长期接触 Linux 的人可能不知道
  • Java应用程序安全框架

    从零打造项目 系列文章 工具 比MyBatis Generator更强大的代码生成器 ORM框架选型 SpringBoot项目基础设施搭建 SpringBoot集成Mybatis项目实操 SpringBoot集成MybatisPlus项目实
  • openGL之API学习(八十四)glGetObjectLabel

    获取命名空间对象的标签 打标签由函数glObjectLabel执行 void glGetObjectLabel GLenum identifier GLuint name GLsizei bufSize GLsizei length cha
  • HTTP反爬困境

    尊敬的程序员朋友们 大家好 今天我要和您分享一篇关于解决反爬困境的文章 在网络爬虫的时代 许多网站采取了反爬措施来保护自己的数据资源 然而 作为程序员 我们有着聪明才智和技术能力 可以应对这些困境并确保数据的安全性 本文将重点介绍如何通过H
  • 如何把简单的事情一次做对?

    在工作中领导最讨厌的人就是总把简单的事情做错的下属 在绝大多数人不会犯错的地方犯错 在领导眼中会判定为是基本素质问题 是不可原谅的 如果组织要裁员 那优先裁掉的就是哪些总是犯低级错误的人 那如何确保能够把简单的事情一次做对 提升自己的职场竞
  • 好用用的linux 监控命令

    1 dstat 命令 参考http www cnblogs com vincent hv p 3358194 html dstat的基本使用 2 1 dstat的默认选项 与许多命令一样 dstat命令有默认选项 执行dstat命令不加任何
  • Angular_与服务器通讯(Websocket通讯)

    在上一篇文章中 我们创建了server服务 在那个项目中我们继续添加websocket服务 npm install ws save 然后安装types格式的 npm install types ws save dev 实现场景 编写服务端
  • “终于懂了” 系列:组件化框架 ARouter 完全解析(二)APT技术

    ARouter系列文章 终于懂了 系列 组件化框架 ARouter 完全解析 一 原理全解 终于懂了 系列 组件化框架 ARouter 完全解析 二 APT 帮助类生成 终于懂了 系列 组件化框架 ARouter 完全解析 二 AGP Tr
  • 物理服务器向虚拟化无缝对接,服务器虚拟化下的网络变迁

    一个风起 云 涌的IT时代 展现的是一种全新的动态IT基础设施 和传统的IT基础设施相比 虚拟化成为目前整个IT基础架构的变革性创新技术 对计算 存储 网络都产生了长远的影响 在数据中心等场景中引入虚拟化技术之后 服务器接入网络的位置往往是
  • C++基础——类与对象的讲解2

    目录 一 类域 二 计算类的大小 类存储方式一 类中包含各个成员 包括函数在内 类存储方式二 类的存储方式三 练习题 三 C 结构内存对齐规则 一 类域 其实类也是个域 拥有一对花括号 它与我们之前学习的命名空间域有相似之处 但也大有不同
  • ovftool工具的使用

    1 工具下载地址 https customerconnect vmware com zh downloads details downloadGroup OVFTOOL440 productId 974 download true file
  • js是实现键盘设置日期(input)

    本功能是基于封装的datetime input框进行的二次封装 加上上下左右修改日期的功能 只提供一种思路 前端框架aurelia formatString formatString country MM DD YY h mm A USA
  • 监控显示服务器超时,国标GB/T28181流媒体服务互联网直播方案EasyGBS录像调取报超时错误如何解决?...

    原标题 国标GB T28181流媒体服务互联网直播方案EasyGBS录像调取报超时错误如何解决 背景分析 视频监控整合人工智能技术 虽然在加强监控的同时也伴随着一些潜在风险 但是潜在的优点显然超过了缺点 且如今人工智能在算法与芯片领域的成熟
  • Packet for query is too large

    mysql 执行insert语句时 提示Packet for query is too large异常 问题点 mysql支持的传输数据包大小超限了 解决办法 比较一劳永逸的方式是直接修改mysql安装目录下的my ini配置文件 增加一行
  • 利用python制作一款截图识别软件

    先给大家推荐一款截图软件 非常方便 可以把截出的图片放置到窗口上 并且可以随意移动 这个是微软开发的一款工具 Snipaste 支持各类电脑系统 先简单介绍一下它的用法 F1截图 ctrl c把图片复制到剪贴板 方便下次使用 ctrl v
  • python协程—asyncio模块

    为什么使用协程 当多线程或者多进程足够多时 实际上并不能解决性能的瓶颈问题 也就是多线程和多进程对小规模的请求可以提高效率 过多的请求实际上会降低服务资源响应效率 因此协程是更好的解决文案 什么是协程 当一个程序遇到阻塞时 如果将这个程序挂