Python协程之协程在手,说走就走
协程在手,说走就走
什么是协程
先介绍–生产者-消费者模式
解释如下
生产者消费者模式并不是GOF提出的23种设计模式之一,23种设计模式都是建立在面向对象的基础之上的,但其实面向过程的编程中也有很多高效的编程模式,生产者消费者模式便是其中之一,它是我们编程过程中最常用的一种设计模式。
在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。
传统的生产者-消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。
如果改用协程,生产者生产消息后,直接通过yield
跳转到消费者开始执行,待消费者执行完毕后,切换回生产者继续生产,效率极高
def consumer():# 消费者r = ''while True:n = yield r # 将r发送出去if not n:returnprint('[CONSUMER] Consuming %s...' % n)r = '200 OK'def produce(c):# 生产者c.send(None) # 启动消费者生成器(虽说叫消费者,但它是生成器),一开始会收到消费者发回来的空字符串n = 0while n < 5:n = n + 1print('[PRODUCER] Producing %s...' % n)r = c.send(n)print('[PRODUCER] Consumer return: %s' % r)c.close()c = consumer() # 类似于iter(range(10)),即
produce(c) # 开始生产
它的输出是这样的
[PRODUCER] Producing 1...
[CONSUMER] Consuming 1...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 2...
[CONSUMER] Consuming 2...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 3...
[CONSUMER] Consuming 3...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 4...
[CONSUMER] Consuming 4...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 5...
[CONSUMER] Consuming 5...
[PRODUCER] Consumer return: 200 OK
生产者每生成一个数,消费者接收到并返回接受状态,细看代码,也就用到了个yield
和send
,但这正是python
实现协程的核心。
首先分析一下代码的执行
生产者首先c.send(None)
,启动消费者生成器,一旦启动生成器,消费者那边的yield
将r
发送到消费者这边,是个空的字符串。
一旦消费者yield
,程序就跑到生产者这边了,消费者就暂停执行,也就是说n = yield r
只执行了yield r
,n
都没有赋值的。
然后消费者这边开始执行while
循环,n
自增,然后就执行r=send(n)
,这边的send
是带参数的,这个参数会发送到消费者那边,给上次的n
进行赋值,也就是说生产者通过send
将消费者从暂停状态激活了。
那么消费者的n
赋值为1后,就继续执行消费者的程序了,打印并且将r
进行赋值,然后又到了yield r
,这就将重新赋值的r
又发送给了生产者的r
。
。。。
就这样一直迭代着,生产者给生产n
,消费者发给生产者r
。
看懂了吗?这到底说了个啥?为什么要这样干?都把人绕晕了…
消费者反而是个生成器,真有意思。
这个模型的核心在于利用yield
实现了函数间的中断,也就是协程的核心。
把上面两个函数看成是两个普通函数,也就是说一个两个函数能够随时中断去执行另外一个函数,这就很神奇了。
定义协程
python提供了async
去定义一个协程函数,await
进行中断挂起去执行其他协程。
import asyncio
import timeasync def main():print('hello')await asyncio.sleep(1)print('world')start = time.time()
asyncio.run(main())
print(f'cost time: {time.time() - start}')
输出
hello
[暂停了一秒]
world
cost time: 1.0051383972167969
定义一个协程就是这么简单,可是这也看不出协程的优点啊,一毫秒的时间也没有节省,那是因为这只有一个协程,也不用切换到其他协程。
那么使用多个协程看一下效果
import asyncio
import timeasync def main():print('hello')await asyncio.sleep(1)print('world')start = time.time()
asyncio.run(asyncio.wait([main(), main()]))
print(f'cost time: {time.time() - start}')
这里使用了两个协程,看一下效果
hello
hello
world
world
cost time: 1.0056376457214355
时间几乎一样,如果不用协程,执行函数肯定最少要2s,但现在只要1s,极大缩短了运行时间。
那么协程和多线程哪个更快呢?有人做了实验进行了对比爬虫协程比线程爬取速度更快? - 北风之神0509 - 博客园 (cnblogs.com)
应用
协程应用比较多的还是IO操作,包括网络IO,文件操作IO,将所有IO操作都进行await
,这样可以极大缩短运行时间。
写代码的时候建议多进程和协程结合使用。
Python协程之协程在手,说走就走相关推荐
- 抽丝剥茧聊Kotlin协程之协程与线程之间的区别
1. 前言 关于协程,可能大家最经常听到的一句话就是"协程是轻量级的线程".一脸懵逼,有没有?这可是官方的slogan,严格意义上讲,一方面官方是想让大家把协程和线程产生一个直观关 ...
- python协程详解_对Python协程之异步同步的区别详解
一下代码通过协程.多线程.多进程的方式,运行代码展示异步与同步的区别. import gevent import threading import multiprocessing # 这里展示同步和异 ...
- python协程和线程_线程和协程之间的区别
线程和协程之间的区别很大,甚至大过进程和线程之间的区别.线程建立在进程之上,协程建立在线程之上.那么协程是什么呢? 协程是一段计算机程序,它一般是一个协作类型的子程序,执行时允许暂停和恢复.协程非常适 ...
- python中的协程(二)
协程 1.协程: 单线程实现并发 在应用程序里控制多个任务的切换+保存状态 优点: 应用程序级别速度要远远高于操作系统的切换 缺点: 多个任务一旦有一个阻塞没有切,整个线程都阻塞在原地,该线程内的其他 ...
- python 多线程和协程结合_一文讲透 “进程、线程、协程”
本文从操作系统原理出发结合代码实践讲解了以下内容: 什么是进程,线程和协程? 它们之间的关系是什么? 为什么说Python中的多线程是伪多线程? 不同的应用场景该如何选择技术方案? ... 什么是进程 ...
- python并发之协程_python并发编程之协程
一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去 ...
- Python与Golang协程异同
背景知识 这里先给出一些常用的知识点简要说明,以便理解后面的文章内容. 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定 ...
- Python中的协程
Python中的协程 文章目录 Python中的协程 一.什么是协程 1.概念 2.协程的好处 3.缺点 二.了解协程的过程 1.yield工作原理 2.协程在运行过程中有四个状态: 3.预激协程的装 ...
- Python并发之协程gevent基础(5)
1,gevent介绍 gevent是第三方库,通过 greenlet 实现 coroutine,创建.调度的开销比 线程(thread) 还小,因此程序内部的 执行流 效率高. gevent 实现了 ...
最新文章
- linux常用命令-date-clock-hwclock-type-whois--help-man-info-cal
- 探索自动驾驶领域中的3D多目标跟踪(ICCV 2021)
- stn算子_在 Excel 中,公式都是以 ____________ 开始的,后面由操作数和运算符构成。...
- vbsedit无法创建空文档_vue文档里你没捡起来的宝藏
- Java Servlet完全教程
- Javascript中for循环
- spark实验遇到的问题
- Excel抽奖小程序
- phpcms如何做企业站-- 替换首页最初操作
- 再次提升2%,仅85K参数的开源人脸检测算法
- 《迅雷链精品课》第十二课:PoW 共识算法
- pc即时聊天所用表情插件的记录
- CEC2018:动态多目标测试函数DF6~DF9的PS及PF
- java、Dom4j、循环迭代递归解析XML,不论是否是叶子节点、有复合结构
- tidb-analyze
- 11210怎么等于24_算24点
- Attention-guided Context Feature Pyramid Network for Object Detection
- 【DB笔试面试608】在Oracle中,如何使用STA来生成SQL Profile?
- 云计算:SaaS、PaaS、IaaS、CaaS并不神秘
- SCA可达性分析基础知识普及