博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python 的协程
阅读量:4228 次
发布时间:2019-05-26

本文共 2154 字,大约阅读时间需要 7 分钟。

yield

既然要说到协程,就不得不先提一下 yield 的用法了,yield 最主要的用法就两种。yield rn = yield r

yield 简要理解:yield 就是 return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后开始。

def foo():    print("starting...")    while True:        res = yield 4        print("res:", res)g = foo()print(next(g))print("-" * 20)print(next(g))
starting...4--------------------res: None4

n = yield r 和 r = c.send(n)

def foo():    print("starting...")    while True:        res = yield 4        print("res:", res)g = foo()print(next(g))print("-" * 20)# print(next(g))print(g.send(7))
starting...4--------------------res: 74

通过上面的例子不难理解,next(g) 和 g.send(param) 其实是比较类似的,只不过后面这个在进行下一步的时候传递了参数进去,或者你也可以认为 next(g) 也传递了参数进去,只不过传递的是 None 而已。

所以,这也可以解释为什么 next(g) 也可以用 g.send(None) 来替换。

如果还有疑问的话,可以看看这篇博客:,相信这篇博客看了之后,你再看下面例子的代码就不那么费劲了 。

协程

协程最大的优势就是极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。

第二大优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。

一般讲协程的时候喜欢用下面这个经典的生产者消费者的例子:

import timedef consumer():    r = ''    while True:        n = yield r        if not n:            return        print('[CONSUMER] Consuming %s...' % n)        time.sleep(1)        r = '200 OK'def produce(c):    c.send(None)    n = 0    while n < 5:        n = n + 1        print('[PRODUCER] Producing %s...' % n)        r = c.send(n)        print('[PRODUCER] Consumer return: %s' % r)    c.close()if __name__ == '__main__':    c = consumer()    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

运行流程:

注意到consumer函数是一个generator,把一个consumer传入produce后:

  1. 首先调用c.send(None)启动生成器 (其实用 next(c) 启动也是可以的);

  2. 然后,一旦生产了东西,通过c.send(n)切换到consumer执行;

  3. consumer通过yield拿到消息,处理,又通过yield把结果传回;

  4. produce拿到consumer处理的结果,继续生产下一条消息;

  5. produce决定不生产了,通过c.close()关闭consumer,整个过程结束。

整个流程无锁,由一个线程执行,produceconsumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。

转载地址:http://aijqi.baihongyu.com/

你可能感兴趣的文章
地理位置服务——navigator.geolocation
查看>>
地理位置服务——百度地图API
查看>>
js拖放事件详解及实战
查看>>
js字符串常用属性与方法
查看>>
C++递归算法案例
查看>>
C++算法——异或运算解决出现次数问题
查看>>
C++数据结构——顺序栈(基本代码实现与案例)
查看>>
C++数据结构——链队列(基本代码实现与案例)
查看>>
C++数据结构——顺序表的查找(简单顺序查找、有序表的二分查找、索引顺序的查找)
查看>>
Hive 常用统计查询语句
查看>>
对象存储产生背景、发展历史、原理架构、优缺点、应用场景及开源项目对比
查看>>
Apache Ozone 分布式对象存储系统相关文档汇总
查看>>
Ozone 与 HDDS 的区别与联系
查看>>
maven失败测试用例rerun插件使用方法
查看>>
Python基础(三)
查看>>
Python入门NLP(二)
查看>>
四行Python代码,你也能从图片上识别文字!
查看>>
内网映射外网工具-ngrok
查看>>
Python带你朗读网页
查看>>
关于python,这些知识点你学会了吗?
查看>>