协程在手,说走就走

什么是协程

先介绍–生产者-消费者模式

解释如下

生产者消费者模式并不是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

生产者每生成一个数,消费者接收到并返回接受状态,细看代码,也就用到了个yieldsend,但这正是python实现协程的核心。

首先分析一下代码的执行

生产者首先c.send(None),启动消费者生成器,一旦启动生成器,消费者那边的yieldr发送到消费者这边,是个空的字符串。

一旦消费者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协程之协程在手,说走就走相关推荐

  1. 抽丝剥茧聊Kotlin协程之协程与线程之间的区别

    1. 前言 关于协程,可能大家最经常听到的一句话就是"协程是轻量级的线程".一脸懵逼,有没有?这可是官方的slogan,严格意义上讲,一方面官方是想让大家把协程和线程产生一个直观关 ...

  2. python协程详解_对Python协程之异步同步的区别详解

    一下代码通过协程.多线程.多进程的方式,运行代码展示异步与同步的区别. import gevent import threading import multiprocessing # 这里展示同步和异 ...

  3. python协程和线程_线程和协程之间的区别

    线程和协程之间的区别很大,甚至大过进程和线程之间的区别.线程建立在进程之上,协程建立在线程之上.那么协程是什么呢? 协程是一段计算机程序,它一般是一个协作类型的子程序,执行时允许暂停和恢复.协程非常适 ...

  4. python中的协程(二)

    协程 1.协程: 单线程实现并发 在应用程序里控制多个任务的切换+保存状态 优点: 应用程序级别速度要远远高于操作系统的切换 缺点: 多个任务一旦有一个阻塞没有切,整个线程都阻塞在原地,该线程内的其他 ...

  5. python 多线程和协程结合_一文讲透 “进程、线程、协程”

    本文从操作系统原理出发结合代码实践讲解了以下内容: 什么是进程,线程和协程? 它们之间的关系是什么? 为什么说Python中的多线程是伪多线程? 不同的应用场景该如何选择技术方案? ... 什么是进程 ...

  6. python并发之协程_python并发编程之协程

    一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去 ...

  7. Python与Golang协程异同

    背景知识 这里先给出一些常用的知识点简要说明,以便理解后面的文章内容. 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定 ...

  8. Python中的协程

    Python中的协程 文章目录 Python中的协程 一.什么是协程 1.概念 2.协程的好处 3.缺点 二.了解协程的过程 1.yield工作原理 2.协程在运行过程中有四个状态: 3.预激协程的装 ...

  9. Python并发之协程gevent基础(5)

    1,gevent介绍 gevent是第三方库,通过 greenlet 实现 coroutine,创建.调度的开销比 线程(thread) 还小,因此程序内部的 执行流 效率高. gevent 实现了 ...

最新文章

  1. linux常用命令-date-clock-hwclock-type-whois--help-man-info-cal
  2. 探索自动驾驶领域中的3D多目标跟踪(ICCV 2021)
  3. stn算子_在 Excel 中,公式都是以 ____________ 开始的,后面由操作数和运算符构成。...
  4. vbsedit无法创建空文档_vue文档里你没捡起来的宝藏
  5. Java Servlet完全教程
  6. Javascript中for循环
  7. spark实验遇到的问题
  8. Excel抽奖小程序
  9. phpcms如何做企业站-- 替换首页最初操作
  10. 再次提升2%,仅85K参数的开源人脸检测算法
  11. 《迅雷链精品课》第十二课:PoW 共识算法
  12. pc即时聊天所用表情插件的记录
  13. CEC2018:动态多目标测试函数DF6~DF9的PS及PF
  14. java、Dom4j、循环迭代递归解析XML,不论是否是叶子节点、有复合结构
  15. tidb-analyze
  16. 11210怎么等于24_算24点
  17. Attention-guided Context Feature Pyramid Network for Object Detection
  18. 【DB笔试面试608】在Oracle中,如何使用STA来生成SQL Profile?
  19. 云计算:SaaS、PaaS、IaaS、CaaS并不神秘
  20. SCA可达性分析基础知识普及

热门文章

  1. TypeScritp数据类型
  2. 知识图谱应用——煤矿安全知识图谱构建技术研究学习
  3. 山东大学 软件学院 2020级 2022年 操作系统 期末考试
  4. ITSS怎么样?对IT行业企业有何意义?
  5. 一步一步教你反向传播的例子
  6. ssh配置免密登录、scp文件传输免密
  7. 抽象数据类型 (ADT)
  8. VUE 子组件向父组件传值的方法
  9. Python中的命名规则
  10. 基于虹软人脸识别Web私有化服务(快速人脸服务集成二次开发)