python 协程asyncio详解

协程

协程就是告诉Cpython解释器,你不是nb吗,不是搞了个GIL锁吗,那好,我就自己搞成一个线程让你去执行,省去你切换线程的时间,我自己切换比你切换要快很多,避免了很多的开销。

协程的本质就是在单线程下,由用户自己控制一个任务遇到io阻塞了就切换另外一个任务去执行,以此来提升效率。为了实现它,我们需要找寻一种可以同时满足以下条件的解决方案:

  1. 可以控制多个任务之间的切换,切换之前将任务的状态保存下来,以便重新运行时,可以基于暂停的位置继续执行。
  2. 作为1的补充:可以检测io操作,在遇到io操作的情况下才发生切换

asyncio☆☆☆☆☆☆

在pyhon3.4的时候推出的,内置模块,不用安装,确保你的Python解释器版本大于3.4

i.直接上代码:

import asyncio@asyncio.coroutine #表示这不再是一个普通函数,已经升级为可以异步的战斗机了!
def func1():print(1)yield from asyncio.sleep(2)  #模拟io,生产中换成实际的ioprint(2)@asyncio.coroutine
def func2():print(3)yield from asyncio.sleep(2)print(4)#把任务放进任务池中
tasks = [asyncio.ensure_future(func1()),asyncio.ensure_future(func2()),
]loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

ii.async & await关键字
Python3.5才出现,保证你的版本符合要求

本质上和上面用法是一样的,只是替换掉关键字而已

import asyncioasync def func1():  #async替换掉关键字print(1)await asyncio.sleep(2)  #等待ioprint(2)async def func2():print(3)await asyncio.sleep(2) print(4)tasks = [asyncio.ensure_future(func1()),#future对象较为底层,是task的基类asyncio.ensure_future(func2()),
]loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

iii.run方法,task对象
Python3.7才出现,保证你的版本符合要求

run方法包含了

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

最常用的协程方法

import asyncioasync def func1():  # async替换掉关键字print(1)await asyncio.sleep(2)  # 等待ioprint(2)return "func1"async def func2():print(3)await asyncio.sleep(2)print(4)return "func2"async def main():tasks = [asyncio.create_task(func1()),  # 必须声名在在异步函数中,因为放在外面没有task对象会报错asyncio.create_task(func2()),]done, pending = await asyncio.wait(tasks, timeout=None)  # done:返回结果,pending:返回未完成的协程函数for i in done:print(i.result())print(pending)# 运行
asyncio.run(main())

若想把tasks对象放在外面,需要修改代码

import asyncioasync def func1():  # async替换掉关键字print(1)await asyncio.sleep(2)  # 等待ioprint(2)return "func1"async def func2():print(3)await asyncio.sleep(2)print(4)return "func2"tasks = [func1(),#不能使用task对象,因为还没有创建事件循环loop对象func2(),
]
#wait方法自动把协程函数创建task对象
done, pending = asyncio.run(asyncio.wait(tasks, timeout=None))  # done:返回结果,pending:返回未完成的协程函数
for i in done:print(i.result())
print(pending)

iv.有些库不支持asyncio语法,如requests
当我们拿着asyncio模块实行异步爬虫的时候

import asyncio
import requestsurls = ["http://www.smilenow.top","http://www.baidu.com","http://www.163.com"
]async def get_cont(url):print("准备下载:", url)htm = requests.get(url=url).textprint(url, "已经下载完毕")return urltasks = map(lambda x: get_cont(x), urls)asyncio.run(asyncio.wait(tasks, timeout=None))  # done:返回结果,pending:返回未完成的协程函数

结果

准备下载: http://www.baidu.com
http://www.baidu.com 已经下载完毕
准备下载: http://www.163.com
http://www.163.com 已经下载完毕
准备下载: http://www.smilenow.top
http://www.smilenow.top 已经下载完毕

什么鬼,根本没有实现异步好吗?怎么办?用线程池替代!

import asyncio
import requestsurls = ["http://www.smilenow.top","http://www.baidu.com","http://www.163.com"
]async def get_cont(url):print("准备下载:", url)loop = asyncio.get_event_loop()future = loop.run_in_executor(None,requests.get,url)#变成多线程方式运行了await futureprint(url, "已经下载完毕")return urltasks = map(lambda x: get_cont(x), urls)asyncio.run(asyncio.wait(tasks, timeout=None))  # done:返回结果,pending:返回未完成的协程函数

v.asyncio 异步操作redis
下载支持异步的redis模块

# pip install aioredisimport aioredis
import asyncioclass Redis:_redis = Noneasync def get_redis_pool(self, *args, **kwargs):if not self._redis:self._redis = await aioredis.create_redis_pool(*args, **kwargs)return self._redisasync def close(self):if self._redis:self._redis.close()await self._redis.wait_closed()async def get_value(key):redis = Redis()r = await redis.get_redis_pool(('127.0.0.1', 6379), db=7, encoding='utf-8')value = await r.get(key)print(f'{key!r}: {value!r}')await redis.close()         if __name__ == '__main__':asyncio.run(get_value('key'))  # need python3.7

vi.aiomysql异步操作mysql
安装:

# pip install aiomysqlimport asyncio
import aiomysqlasync def execute():conn = await aiomysql.connect(host='localhost', port=3306, user="root", password='123', db='my')cur = await conn.cursor()await cur.excute("select * from user")result = await cur.fetchall()print(result)await cur.close()await conn.close()asyncio.run(execute())

v.不够快,uvloop让速度飞翔!!!
uvloop 使得 asyncio 更快. 实际上,比nodejs,gevent,以及其他任何Python异步框架至少快两倍 .uvloop asyncio 基于性能的测试接近于Go程序.

这是一个被各大框架青睐的模块

安装:pip install uvloop


import asyncio
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())#下面正常书写asyncio代码

————————————————
版权声明:本文为CSDN博主「卢政孝simi」的原创文章

原文链接:https://blog.csdn.net/qq_40837794/article/details/109708891

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/201977.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Docker】从零开始:13.Docker安装tomcat

Docker】从零开始:13.Docker安装Tomcat 下载Tomcat镜像启动Tomcat镜像新版本Tomcat修改访问Tomact首页 下载Tomcat镜像 [rootdocker ~]# docker pull tomcat Using default tag: latest latest: Pulling from library/tomcat 0e29546d541c: Pull complete 9b829c7…

uniapp横向滚动示例

目录 插件市场案例最后 插件市场 地址 案例 地址 最后 感觉文章好的话记得点个心心和关注和收藏,有错的地方麻烦指正一下,如果需要转载,请标明出处,多谢!!!

简述IO流的使用以及使用时需要注意的事项

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍介绍IO流的使用以及使用时需要注意的事项以及部分理论知识 🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁 🍉博主收将持续更新学习记录获,友友们有任何问题可…

程序员都在收藏的免费好用API接口

AI绘画-Mid Journey:使用 Midjourney 目前全球领先的图片大模型,其能根据输入文字提供极其优秀的AI绘画作品。AI绘画-Stable Diffusion:通过AI 生成图片,包括图生文、文生图等。IP归属地-IPv4区县级:根据IP地址查询归属…

11月榜单丨飞瓜数据B站UP主排行榜(哔哩哔哩平台)发布!

飞瓜轻数发布2023年11月飞瓜数据UP主排行榜(B站平台),通过充电数、涨粉数、成长指数、带货数据等维度来体现UP主账号成长的情况,为用户提供B站号综合价值的数据参考,根据UP主成长情况用户能够快速找到运营能力强的B站U…

Linux Console快捷键

Ctrl C:终止当前正在运行的程序。 Ctrl D:关闭当前终端会话。 Ctrl Z:将当前程序放入后台运行。 Ctrl L:清除当前屏幕并重新显示命令提示符。 Ctrl R:在历史命令中进行逆向搜索。 Ctrl A:将光标移动到…

java--泛型方法、通配符、上下限

1.泛型方法 2.通配符 就是"?",可以在"使用泛型"的时候代表一切类型;E T K V是在定义泛型的时候使用。 3.泛型的上下限 ①泛型上限:? extends Car:? 能接收的必须是Car或者其子类 ②泛型下限&#xff1…

ubuntu安装MySQL8

1.下载mysql8 MySQL :: Download MySQL Installer (Archived Versions) 选择对应的mysql版本和对应的ubuntu版本图即可 2.下载后上传到sftp文件夹中,然后通过以下命令解压 tar -xvf mysql-server_8.0.29-1ubuntu20.04_amd64.deb-bundle.tar 3.依次安装即可 &#…

Auth的使用、缓存

auth 是什么,有什么作用 auth就是django 的一个app,做用户管理 Auth模块是Django自带的用户认证模块: 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销…

Sql Server 2017主从配置之:AlwaysOn高可用

AlwaysOn高可用功能,真正实现了数据库的灾备切换、高可用。 AlwaysOn通过Windows Server故障转移群集,部署高可用数据库组。 在故障转移群集基础上完成部署读写分离,只读负载平衡最多3个写入节点实现故障转移最多3个数据实时同步节点 环境…

西门子SMART精彩触摸屏如何在进入某个画面时置位某个BOOL变量?

西门子SMART精彩触摸屏如何在进入某个画面时置位某个BOOL变量? 以下举例进行说明具体的操作: 如下图所示,新建一个项目后,在变量表中添加好自己需要的变量; 添加一个画面,这里以“画面_1”进行举例说明&…

数据库事务详解

事务特性:acid;aid为了实现c 原子性:一个事务要么全执行,要么全不执行-》回滚 sqlite是备份 其他是失败执行语义的反向操作-》算法 一致性: 完整性约束在一个事务执行后没有被破坏:主键约束,外键约束,自…

【链表Linked List】力扣-24 两两交换链表中的节点

目录 题目描述 解题过程 题目描述 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例 1: 输入:he…

【1day】致远A6系统任意文件下载漏洞学习

注:该文章来自作者日常学习笔记,请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与作者无关。 目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现

安科瑞智慧型动态无功补偿的工业应用—— 以江苏某陶瓷生产企业配电房改造为例

安科瑞电气股份有限公司 摘 要:低压配电系统的无功补偿是电能质量治理的重要环节。在传统无功补偿中,响应速度较慢,补偿电流呈阶梯式,存在过补或欠补的现象,有时未必能到达理想的效果。为了解决这一问题,…

二极管:ESD静电保护二极管

一、什么是ESD二极管 ESD二极管与 TVS二极管原理是一样的,也是为了保护电,但ESD二极管的主要功能是防止静电。 静电防护的前提条件就要求其电容值要足够地低,一般在1PF-3.5PF之间最好,主要应用于板级保护。 二、什么是静电 静…

软件科技成果鉴定测试有什么好处?注意事项有哪些?

软件科技成果鉴定测试是指对软件科技成果进行检测和评估的过程。通过这个测试,可以评估软件科技成果的技术水平、功能性能以及可靠性,并为相关单位和个人提供科学的评价依据。    一、进行软件科技成果鉴定测试有以下好处:   1、客观评价…

什么?你还不会 OpenTiny 跨框架组件库适配微前端?

本文由体验技术团队 TinyVue 组件库成员陈家梅同学分享,带你手把手实现 TinyVue 组件库适配微前端~ 一、前言 以下是我对微前端的一些粗浅理解,对微前端有一定了解的话可以略过,直接进入第二部分。 1、微前端是什么? 我们首先…

AI智能批量写作的工具,免费AI智能写作工具

文本创作成为各行业不可或缺的一环。然而,随着信息量的急剧增长,传统的手工写作方式已经难以满足大规模文本需求。AI智能批量写作作为一项前沿技术,本文将深入探讨AI智能批量写作的方法,介绍一些知名的工具,并对它们进…

东南大学与OpenHarmony携手共建开源生态,技术俱乐部揭牌成立并迎来TSC专家进校园

11月25日,OpenAtom OpenHarmony(以下简称“OpenHarmony”)项目群技术指导委员会(以下简称“TSC”)与东南大学携手,于东南大学九龙湖校区金智楼一楼报告厅举办了“东南大学OpenHarmony技术俱乐部成立仪式暨OpenHarmony TSC专家进校园”活动。此次盛会标志着OpenHarmony开源社区和…