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 异步编程---协程相关推荐

  1. python asyncio 异步编程-协程 2

    asyncio 异步编程 官方文档: 中文版:https://docs.python.org/zh-cn/3.8/library/asyncio.html 英文本:https://docs.pytho ...

  2. python asyncio教程_Python 协程模块 asyncio 使用指南

    Python 协程模块 asyncio 使用指南 前面我们通过5 分钟入门 Python 协程了解了什么是协程,协程的优点和缺点和如何在 Python 中实现一个协程.没有看过的同学建议去看看.这篇文 ...

  3. python——asyncio模块实现协程、异步编程(一)

    我们都知道,现在的服务器开发对于IO调度的优先级控制权已经不再依靠系统,都希望采用协程的方式实现高效的并发任务,如js.lua等在异步协程方面都做的很强大. python在3.4版本也加入了协程的概念 ...

  4. python——asyncio模块实现协程、异步编程(三)

    [八]协程停止 future对象有几个状态: Pending Running Done Cancelled 创建future的时候,task为pending,事件循环调用执行的时候当然就是runnin ...

  5. python——asyncio模块实现协程、异步编程(二)

    [六]协程并发 定义tasks时可以设置多个ensure,也可以像多线程那样用append方法实现 tasks = [asyncio.ensure_future(coroutine1),asyncio ...

  6. python find()效率_基于python分别采用同步与异步(协程)方式抓取时光网TOP100电影...

    欢迎各位小哥哥小姐姐阅读本的文章,对大家学习有帮助,请点赞加关注哦!!!!!!!!!! 您的点赞和关注将是我持续更新的动力呢.^v^ 有不懂的问题可以私聊我哦! 如题,同步运行就是python按照代码 ...

  7. Python之进程+线程+协程(异步、selectors模块、阻塞、非阻塞IO)

    文章目录 一.IO多路复用 二.selectors模块 本篇文字是关于IO多路复用的更深入一步的总结,上一篇 Python之进程+线程+协程(事件驱动模型.IO多路复用.select与epoll)对I ...

  8. python异步爬虫协程的使用学习笔记

    最近学异步的时候对于协程的理解比较困难,感觉对于之前的多线程也有也陌生了(下个文章写一下多线程巩固一下) 目录 先来说明一下协程的定义: asynico库使用 一 . event_loop事件循环 二 ...

  9. Python 异步,协程,学起来好头疼,Python爬虫程序能调用GPU去爬东西吗?

    78 技术人社群日报时间 文章目录 Python 爬虫程序能调用 GPU 去爬东西吗? Python 异步,协程--,学起来好头疼 有没有牛子大的说下 `matplotlib` 里 `plot` 和 ...

最新文章

  1. 学习java得一些笔记(5)
  2. linux方向键ascii_上下左右 方向键的ASCII码值是多少?
  3. Selleck --- 01Cookie
  4. 5元以下纯铜小摆件_下一轮牛市即将在2020年登陆?现在能否买入5元以下低价股一直持有到牛市结束?出乎意料...
  5. 基于sklearn 的one hot encoding
  6. vs2013 旗舰版 密钥
  7. 论文阅读《Revisiting Domain Generalized Stereo Matching Networks from a Feature Consistency Perspective》
  8. 蓝筹股是什么意思?低估值蓝筹股有哪些?拥有蓝筹股的好处?
  9. Typhoon-v1.02渗透笔记
  10. 显卡无法为此计算机,如何解决win10系统电脑中无法安装intel显卡驱动的问题
  11. 论坛报名 | 语音与自然语言处理的最新突破和前沿趋势。道翰天琼认知智能平台为您揭秘新一代人工智能-1。
  12. git和github使用
  13. 520情人节|用Python跟‘喜欢的人’表白
  14. 互联网公司面试题以及范围
  15. 常见互联网公司职级和薪资一览!
  16. DJ logo图片 DJ logo设计
  17. docker安装oracle11g史上最全步骤
  18. Bootstrap引用Glyphicons 字体图标
  19. 所有伟大的创新,本质上都是从一小撮年轻人肆无忌惮打破规则开始的
  20. 十种数据挖掘分析法:一种算法就能独步天下

热门文章

  1. 塔菲克蓝牙适配器驱动_小身材,大功能,biaze毕亚兹USB蓝牙适配器开箱体验
  2. 如何在计算机课上渗透德育教育初探,在《道德与法治》课中德育渗透的案例初探...
  3. python 保存文件 吃内存_孤荷凌寒自学python第三十七天python的文件与内存变量之间的序列化与反序列化...
  4. python修改mac地址_python利用_winreg模块制作MAC地址修改工具
  5. python3语音识别模块_『开源项目』基于STM32的智能垃圾桶之语音识别
  6. 手握顶会顶刊论文,自信满满面试算法岗竟被刷?
  7. 消息中间件系列(六):什么是流量削峰?如何解决秒杀业务的削峰场景
  8. 技术动态 | 清华大学开源OpenKE:知识表示学习平台
  9. app = Flask(__name__)相关说明
  10. 令人振奋的好消息!2016年12月8日Google Developers中文网站发布!