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 中处理单值元组的最佳实践是什么?

    我正在使用第三方库函数 它从文件中读取一组关键字 并且应该返回一个值的元组 只要有至少两个关键字 它就能正确执行此操作 但是 在只有一个关键字的情况下 它返回一个原始字符串 而不是大小为 1 的元组 这是特别有害的 因为当我尝试做类似的事情
  • Ajax 调用后使用 Django 模板呈现 JSON 对象

    我一直在尝试了解什么是最佳方法Ajax http en wikipedia org wiki Ajax 28programming 29 in Django http en wikipedia org wiki Django 28web f
  • Python动态导入脚本,需要有其__name__ == "__main__"代码才能被调用

    当从另一个脚本导入 python 脚本时 我想要受经典保护的脚本代码 if name main 要运行 我怎样才能运行该代码 我想做的是从 python 脚本动态更改模块 然后导入现有脚本 该脚本应该看到所做的更改并运行其 main 像Py
  • 从终端调用时 uvicorn 不工作

    我尝试通过 pip3 在系统上安装 uvicorn 这有效 但是我无法从命令行运行相同的命令 有关如何解决此问题的任何指示 Requirement already satisfied uvicorn in home vhawk19 loca
  • 出现导入错误:无法从“随机”导入名称“随机”[重复]

    这个问题在这里已经有答案了 我在我的计算机上多次运行我的代码 但没有出现此错误 但突然间这个来了 File e Python 3 8 0 lib site packages comtypes client code cache py lin
  • 如何使用泛型类型的构造函数

    如何使用 python 泛型类型的构造函数 T typing TypeVar T class MyClass typing Generic T def init self initialValue typing Iterable self
  • numpy 数组最快的保存和加载选项

    我有一个生成二维的脚本numpy数组与dtype float和形状的顺序 1e3 1e6 现在我正在使用np save and np load对数组执行 IO 操作 然而 这些函数对于每个数组都需要几秒钟的时间 是否有更快的方法来保存和加载
  • 在 Ubuntu 上使用 Python 获取显示器分辨率

    对于 Ubuntu win32api 中是否有与 GetSystemMetrics 相当的代码 我需要获取显示器的宽度和高度 以像素为单位 我可以建议一些可以使用的方法 不过我还没有使用过 xlib 版本 1 xlib Python 程序的
  • 在 (i)python 脚本中从 jupyter 内核获取输出

    我想从单个 ipython 会话中打开多个内核 在这些内核上运行代码 然后收集结果 但我不知道如何收集结果 甚至不知道如何查看 stdout stderr 我怎样才能做这些事情呢 到目前为止我所得到的 我已经使用如下代码管理了前两个步骤 打
  • 对于 pygtk 应用程序来说,什么是好的嵌入式浏览器?

    我计划在我的 pygtk 应用程序中使用嵌入式浏览器 并且我正在 gtkmozembed 和 pywebkitgtk 之间进行辩论 两者之间有什么引人注目的区别吗 还有我不知道的第三种选择吗 应该注意的是 我不会使用它来访问网络上的内容 我
  • 尝试修复我的功能

    我正在开发一个函数 我必须返回一个元组 其中第一个参数是最大数字的 str 第二个参数是 int 列表 这是示例以及我为该函数编写的内容 投票 G G N G C G 1 3 0 1 您必须将最大值的位置映射到正确的一方 parties N
  • 多线程写入文件

    前几天刚开始使用 python 对多线程的整个概念还很陌生 我在多线程时写入文件时遇到问题 如果我按照常规方式执行此操作 它会不断覆盖正在写入的内容 使用 5 个线程写入文件的正确方法是什么 不降低性能的最佳方法是在所有线程之间使用队列 每
  • 在Python中引用不带换行符的长字符串

    我正在尝试在 Python 中编写一个长字符串 该字符串显示为 OptParser 选项的帮助项 在我的源代码 py 文件中 我想放置换行符 以便我的代码不会花费新行 但是 我不希望这些换行符影响代码运行时该字符串的显示方式 例如 我想写
  • 在 Django/python 中,如何将内存缓存设置为无限时间?

    cache set key value 9999999 但这并不是无限的时间 def get memcache timeout self timeout Memcached deals with long gt 30 days timeou
  • 检测图像是否损坏或损坏

    我需要以编程方式检查用户在我的应用程序上选择作为壁纸的图像是否已损坏或损坏 基本上我为用户提供了选择自己的图像作为壁纸的选项 现在 当图像加载时 我只想检查它是否已损坏 如果您正在寻找 PHP 解决方案而不是 javascript 解决方案
  • 安排 Asyncio 任务每 X 秒执行一次?

    我正在尝试创建一个 python 不和谐机器人 它将每隔 X 秒检查一次活跃会员 并根据会员的在线时间奖励积分 我正在使用 asyncio 来处理聊天命令 这一切都正常 我的问题是找到一种方法来安排每隔 X 秒异步检查一次活动成员 我已经阅
  • 使用 Pandas 和 Group By 绘制堆叠直方图

    我正在使用如下所示的数据集 Gender Height Width Male 23 4 4 4 Female 45 4 4 5 我想可视化高度和宽度的堆叠直方图 我希望每个图有两个堆叠的直方图 每个性别一个 这是文档中的堆叠直方图 如果存在
  • python pandas如何在多个条件下过滤字符串

    我有以下数据框 import pandas as pd data 5Star FiveStar five star fiv estar data pd DataFrame data columns columnName 当我尝试用一 种条件
  • 连接运算符 + 或 ,

    var1 abc var2 xyz print literal var1 var2 literalabcxyz print literal var1 var2 literal abc xyz 除了带有 的自动空格之外 两者有什么区别 哪个通
  • Python列表问题

    我在使用 python 列表时遇到问题 简化版本是 mylist1 some items in a list mylist2 mylist1 mylist1 pop i mylist insert i item print mylist1

随机推荐

  • 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模块

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