Python 异步编程之——协程
1.总则
多进程可以实现真正的并行,但进程间无法进行直接通信且占用资源较多。多线程的使用代价相对多进程较小,但为了解决数据安全问题引入了锁的机制。这又使得多线程并发度降低,同时,使用锁还可能造成死锁。
在此背景下,协程出现了。协程是单线程,是任务级的切换。相比线程和进程切换,代价小得多,并发性能也很高。
2.实现原理
上面提到,协程是任务级的切换,具体地说就是函数级的切换。这句话展开有两个要点。①要有一个负责切换函数执行的循环;②函数要能暂停和重启。函数要实现暂停和重启,就要引入生成器的概念。
(1)生成器——函数暂停和重启
简单讲,函数内部使用了关键字yield就是生成器。
def gen_fun():yield 1yield 2g = gen_fun()
print(next(g))
print(next(g))# 输出:12
生成器函数和普通函数相比,首先是使用了yield。yield和return都可以返回值。但return只能有一个,yield可以有多个;return是函数的结束,yield只是暂停,下一次调用会从上一次暂停的地方继续执行。为了展现“继续执行”,我们把上面的例子补充下:
def gen_fun():yield 1yield 2yield 3g = gen_fun()
print(next(g))
print('-------上次执行-------')
for num in g:print(num)# 输出:1-------上次执行-------23
可以看到,for循环的值是从2开始的,因为第一个yield已经被next()执行了。有了生成器,函数的暂停和重启也就实现了。yield除了可以返回值也可以接收值(关于更多生成器的知识,单独总结)
yield既可以实现生成器,也可以实现协程。为了使语义更明确,一般使用async-await实现协程。具体例子放在下面一起呈现。
(2)事件循环
可以使用while循环去遍历任务,监听,某任务有返回,则获取返回值做下一步操作(相对复杂)。也可以直接使用python(3.5以后)自带的异步IO——asyncio创建循环。且,其使用方式和多线程、多进程相似,保证了接口的一致性。
async def downloader(url):print('准备从{}下载内容'.format(url))# 模拟下载,不能使用time.sleep,会阻塞单线程await asyncio.sleep(3)return '这是从{}下载的内容,'.format(url)async def handle(url):html = await downloader(url)print(html+'这是下载后进一步的处理')return htmlif __name__ == "__main__":urls = ["http://www.baidu.com", "http://www.sina.com"]# 创建事件循环loop = asyncio.get_event_loop()start_time = time.time()tasks = [handle(url) for url in urls]loop.run_until_complete(asyncio.wait(tasks))print("耗时:", time.time()-start_time)# 输出:准备从http://www.sina.com下载内容准备从http://www.baidu.com下载内容这是从http://www.sina.com下载的内容,这是下载后进一步的处理这是从http://www.baidu.com下载的内容,这是下载后进一步的处理耗时: 3.000380754470825
从最终输出打印的顺序和耗时就可以看出,协程是如何运作并实现并发的。当第一个url传到downloader的时候,我使用asyncio.sleep(3)模拟等待下载的时间。而线程并没有阻塞在这里,而是在等待的时候暂停了这个函数的执行(没有继续往下执行),并提交了第二个url请求。因此,先打印了两个“准备从xx下载内容”,当第一个url请求返回了结果,调度又切换回来继续执行。返回结果并交由handle处理。最后,从耗时也可以看出,两个请求都等待3s,使用协程的总耗时却不是6s。因此,我们使用协程实现了并发。
3.注意事项
协程里不能使用阻塞式代码(如time.sleep)和阻塞式第三方库(requests,pymysql)
关于asyncio更多知识,如其他创建任务方式,聚合任务,取消任务,获取任务返回等知识,单独总结。
Python 异步编程之——协程相关推荐
- python 异步编程:协程与 asyncio
文章目录 一.协程(coroutine) 1.1 协程的概念 1.2 实现协程的方式 二.asyncio 异步编程 2.1 事件循环 2.2 快速上手 2.3 运行协程 2.4 await 关键字 2 ...
- python并发编程:协程asyncio、多线程threading、多进程multiprocessing
python并发编程:协程.多线程.多进程 CPU密集型计算与IO密集型计算 多线程.多进程与协程的对比 多线程 创建多线程的方法 多线程实现的生产者-消费者爬虫 Lock解决线程安全问题 使用线程池 ...
- python并发编程之协程
python并发编程之协程 1.协程: 单线程实现并发 在应用程序里控制多个任务的切换+保存状态 优点: 应用程序级别速度要远远高于操作系统的切换 缺点: 多个任务一旦有一个阻塞没有切,整个线程都阻塞 ...
- Python 异步 IO 、协程、asyncio、async/await、aiohttp
From :廖雪峰 异步IO :https://www.liaoxuefeng.com/wiki/1016959663602400/1017959540289152 Python Async/Awai ...
- python3异步编程_协程 Python异步编程(asyncio)
协程(Coroutine) 也可以被称为微线程,是一种用户态内的上下文切换技术.简而言之,其实就是通过一个线程实现代码块相互切换执行. 直接上代码,例如: 同步编程 import time def f ...
- Python异步爬虫之协程抓取妹子图片(aiohttp、aiofiles)
目录 前言 一.什么是协程? 二.协程的优势 三.代码分析 1.引入库 2.获取所有时间线的链接 3.获取一个时间线中所有相册的链接 4.获取一个相册中所有的图片链接以及相册的名字 5.下载并保存图片 ...
- python协程编程实例_Python异步编程之协程任务的调度操作实例分析
{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...
- 深入理解Python异步编程
声明:本文为转载内容 前言 很多朋友对异步编程都处于"听说很强大"的认知状态.鲜有在生产项目中使用它.而使用它的同学,则大多数都停留在知道如何使用 Tornado.Twisted. ...
- 深入理解 Python 异步编程
原文地址:点击打开链接 来源:阿驹(微信公号:驹说码事) 如有好文章投稿,请点击 → 这里了解详情 前言 很多朋友对异步编程都处于"听说很强大"的认知状态.鲜有在生产项目中使用它. ...
最新文章
- 2022-2028年中国汽车铝合金冲压件行业市场运营模式及未来发展潜力报告
- python属性访问顺序_Python 对象属性的访问
- 清华大学人工智能研究院成立大数据智能研究中心
- 华为机试题【9】-整数分割为2的幂次
- java -锁(公平、非公平锁、可重入锁【递归锁】、自旋锁)
- Redis夺命十二问,你能扛到第几问?
- MySQL基础(一)介绍和配置
- python基础案例教程_Python基础教程 两个经典案例:阶乘和幂
- 消息称华为计划推出自有品牌电动汽车 官方重申不造车
- html文档含有阿拉伯文,html – iOS中包含自定义字体的阿拉伯文字
- matlab中复华simpson,MATLAB Simpson的规则
- mqtt 服务器 ca 证书,如何将SSL MQTT客户机与CA签名服务器证书连接?
- springboot之整合slf4j
- B端产品的PMF的定义原则
- redis-发布与订阅
- 数据库的基本操作习题
- 没有 XXX 的手册页条目问题解决
- java Web 前后端交互
- 命令行快速清理Mac版搜狗输入法
- 武大计算机博士很难毕业,武大的博士好考吗?好毕业吗?