python asyncio 异步编程---协程
1、协程
官方描述;
协程是子例程的更一般形式。 子例程可以在某一点进入并在另一点退出。 协程则可以在许多不同的点上进入、退出和恢复。 它们可通过 async def 语句来实现。 参见 PEP 492。
协程不是计算机内部提供的,不像进程、线程,由电脑本身提供,它是由程序员人为创造的, 实现函数异步执行。
协程(Coroutine),也可以被称为微线程,是一种用户太内的上下文切换技术,其实就是通过一个线程实现代码块相互切换执行。看上去像子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。例如:
# 需要python3.7+
import asyncioasync def main():print('hello')await asyncio.sleep(1)print('world')asyncio.run(main())# 打印 "hello",等待 1 秒,再打印 "world"
注意:简单地调用一个协程并不会使其被调度执行,
直接main() 调用会有问题:
RuntimeWarning: coroutine 'main' was never awaitedmain()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
def func1():print(1)...print(2)def func2():print(3)...print(4)func1()
func2() # 结果:1 2 3 4
实现协程的方法:
- greenlet,早期模块【不建议使用】
- yield关键字,它是python的生成器,具有保存状态,切换到其他函数去执行,再切换回原函数的功能。
- asyncio装饰器(python3.4引入)
- async、await 关键字(python3.5)【推荐使用】
1.1 greenlet实现协程
# 第三方模块,因此需要安装pip install greenlet
from greenlet import greenletdef func1():print(1)gr2.switch()print(2)gr2.switch()def func2():print(3)gr1.switch()print(4)gr1 = greenlet(func1)
gr2 = greenlet(func2)gr1.switch()# 结果:1 3 2 4
1.2 yield关键字
def func1():yield 1yield from func2()yield 2def func2():yield 3yield 4f1 = func1()
for item in f1:print(item)# 结果:1 3 2 4
1.3 asynico装饰器
python3.4 及之后版本支持
DeprecationWarning: “@coroutine” decorator is deprecated since Python 3.8, use “async def”
翻译:@coroutine"装饰器自Python 3.8起已弃用,请使用"async def"代替
所以这个也不支持。
import asyncio@asyncio.coroutine
def func1():print(1)yield from asyncio.sleep(2) # 遇到IO耗时操作,自动切换到tasks中其他任务,比如:网络IO,下载图片print(2)@asyncio.coroutine
def func2():print(3)yield from asyncio.sleep(2) # 遇到IO耗时操作,自动切换到tasks中其他任务,比如:网络IO,下载图片print(4)tasks = [asyncio.ensure_future(func1()),asyncio.ensure_future(func2())
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))# 结果: 1 3 2 4
1.4 async & await 关键字
import asyncioasync def func1():print(1)await asyncio.sleep(2) # 遇到IO耗时操作,自动切换到tasks中其他任务,比如:网络IO,下载图片print(2)async def func2():print(3)await asyncio.sleep(2) # 遇到IO耗时操作,自动切换到tasks中其他任务,比如:网络IO,下载图片print(4)tasks = [asyncio.ensure_future(func1()),asyncio.ensure_future(func2())
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
2. 协程的意义
充分利用线程。在一个线程中如果遇到IO等待时间线程不会一直等待,利用空闲时间再去干点其他事情。
以下载三张图片为例:
- 普通方式(同步)下载:
import time
import requestsdef download_image(url, img_name):print("开始下载:", url)# 发送网络请求,下载图片response = requests.get(url)print("下载完成")# 图片保存到本地文件file_name = str(img_name) + '.png'with open(file_name, mode='wb') as file:file.write(response.content)if __name__ == '__main__':start = time.time()url_list = ['https://tse4-mm.cn.bing.net/th/id/OIP.866vRxQ8QvyDsrUuXiu7qwHaNK?w=182&h=324&c=7&o=5&pid=1.7','https://tse2-mm.cn.bing.net/th/id/OIP.HUcWtoYPG-z2pu4ityajbAHaKQ?w=182&h=252&c=7&o=5&pid=1.7','https://tse2-mm.cn.bing.net/th/id/OIP.MvncR0-Pt9hVxKTdrvD9dAHaNK?w=182&h=324&c=7&o=5&pid=1.7','https://tse1-mm.cn.bing.net/th/id/OIP._nGloaeMWbL7NB7Lp6SnXQHaLH?w=182&h=273&c=7&o=5&pid=1.7',]img_name = 1for item in url_list:download_image(item, img_name)img_name += 1end = time.time()print(end - start)# 最终时间:7.25s
- 协程方式(异步)下载:
import aiohttp
import asyncio
import timeasync def fetch(session, url):print("发送请求:", url)async with session.get(url, verify_ssl=False) as response:content = await response.content.read()file_name = url.rsplit('_')[-1]# print(file_name)with open(file_name, mode='wb') as file_object:file_object.write(content)print("下载完成")async def main():async with aiohttp.ClientSession() as session:url_list = ['https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg','https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg','https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg','https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg',]tasks = [asyncio.ensure_future(fetch(session, url)) for url in url_list]await asyncio.wait(tasks)if __name__ == '__main__':start = time.time()asyncio.get_event_loop().run_until_complete(main())end = time.time()print(end - start)# 结果:0.05s
python asyncio 异步编程---协程相关推荐
- python asyncio 异步编程-协程 2
asyncio 异步编程 官方文档: 中文版:https://docs.python.org/zh-cn/3.8/library/asyncio.html 英文本:https://docs.pytho ...
- python asyncio教程_Python 协程模块 asyncio 使用指南
Python 协程模块 asyncio 使用指南 前面我们通过5 分钟入门 Python 协程了解了什么是协程,协程的优点和缺点和如何在 Python 中实现一个协程.没有看过的同学建议去看看.这篇文 ...
- python——asyncio模块实现协程、异步编程(一)
我们都知道,现在的服务器开发对于IO调度的优先级控制权已经不再依靠系统,都希望采用协程的方式实现高效的并发任务,如js.lua等在异步协程方面都做的很强大. python在3.4版本也加入了协程的概念 ...
- python——asyncio模块实现协程、异步编程(三)
[八]协程停止 future对象有几个状态: Pending Running Done Cancelled 创建future的时候,task为pending,事件循环调用执行的时候当然就是runnin ...
- python——asyncio模块实现协程、异步编程(二)
[六]协程并发 定义tasks时可以设置多个ensure,也可以像多线程那样用append方法实现 tasks = [asyncio.ensure_future(coroutine1),asyncio ...
- python find()效率_基于python分别采用同步与异步(协程)方式抓取时光网TOP100电影...
欢迎各位小哥哥小姐姐阅读本的文章,对大家学习有帮助,请点赞加关注哦!!!!!!!!!! 您的点赞和关注将是我持续更新的动力呢.^v^ 有不懂的问题可以私聊我哦! 如题,同步运行就是python按照代码 ...
- Python之进程+线程+协程(异步、selectors模块、阻塞、非阻塞IO)
文章目录 一.IO多路复用 二.selectors模块 本篇文字是关于IO多路复用的更深入一步的总结,上一篇 Python之进程+线程+协程(事件驱动模型.IO多路复用.select与epoll)对I ...
- python异步爬虫协程的使用学习笔记
最近学异步的时候对于协程的理解比较困难,感觉对于之前的多线程也有也陌生了(下个文章写一下多线程巩固一下) 目录 先来说明一下协程的定义: asynico库使用 一 . event_loop事件循环 二 ...
- Python 异步,协程,学起来好头疼,Python爬虫程序能调用GPU去爬东西吗?
78 技术人社群日报时间 文章目录 Python 爬虫程序能调用 GPU 去爬东西吗? Python 异步,协程--,学起来好头疼 有没有牛子大的说下 `matplotlib` 里 `plot` 和 ...
最新文章
- 学习java得一些笔记(5)
- linux方向键ascii_上下左右 方向键的ASCII码值是多少?
- Selleck --- 01Cookie
- 5元以下纯铜小摆件_下一轮牛市即将在2020年登陆?现在能否买入5元以下低价股一直持有到牛市结束?出乎意料...
- 基于sklearn 的one hot encoding
- vs2013 旗舰版 密钥
- 论文阅读《Revisiting Domain Generalized Stereo Matching Networks from a Feature Consistency Perspective》
- 蓝筹股是什么意思?低估值蓝筹股有哪些?拥有蓝筹股的好处?
- Typhoon-v1.02渗透笔记
- 显卡无法为此计算机,如何解决win10系统电脑中无法安装intel显卡驱动的问题
- 论坛报名 | 语音与自然语言处理的最新突破和前沿趋势。道翰天琼认知智能平台为您揭秘新一代人工智能-1。
- git和github使用
- 520情人节|用Python跟‘喜欢的人’表白
- 互联网公司面试题以及范围
- 常见互联网公司职级和薪资一览!
- DJ logo图片 DJ logo设计
- docker安装oracle11g史上最全步骤
- Bootstrap引用Glyphicons 字体图标
- 所有伟大的创新,本质上都是从一小撮年轻人肆无忌惮打破规则开始的
- 十种数据挖掘分析法:一种算法就能独步天下
热门文章
- 塔菲克蓝牙适配器驱动_小身材,大功能,biaze毕亚兹USB蓝牙适配器开箱体验
- 如何在计算机课上渗透德育教育初探,在《道德与法治》课中德育渗透的案例初探...
- python 保存文件 吃内存_孤荷凌寒自学python第三十七天python的文件与内存变量之间的序列化与反序列化...
- python修改mac地址_python利用_winreg模块制作MAC地址修改工具
- python3语音识别模块_『开源项目』基于STM32的智能垃圾桶之语音识别
- 手握顶会顶刊论文,自信满满面试算法岗竟被刷?
- 消息中间件系列(六):什么是流量削峰?如何解决秒杀业务的削峰场景
- 技术动态 | 清华大学开源OpenKE:知识表示学习平台
- app = Flask(__name__)相关说明
- 令人振奋的好消息!2016年12月8日Google Developers中文网站发布!