python3协程学习笔记

python3 协程, yield, yield from

协程的应用

在此之前,协程对我来说是一个比较陌生的概念,学习之后,发现其应用场景还是有不少,大师之言:

协程能自然地表述很多算法,例如仿真、游戏、异步I/O,以及其他事件驱动型边吃形式活协作式多任务。

举例来说,asyncio、Tornado、Twisted、simPy库都是基于协程特性在单个线程中管理多个并发活动。

协程和线程

有人将线程和协程混为一谈,概念上讲,协程,又称微线程、纤程,英文名 Coroutine。它类似于子例程,但执行过程中,在子例程内部可中断,然后转而执行别的子例程,在适当的时候再返回来接着执行。
简单来说,线程更多是抢占式线程,协程是协作式线程。两者更大的区别在于你认为哪个调度策略更符合你的实际场景,线程调度有操作系统管理,协程调度完全有开发者管理,协程上下文切换现在是在用户空间,因此调度的成本相对较低,不过也不代表这就是高效的。我们可以笼统地认为在面对 IO 密集型任务的时候,协程更高效,因为绝大部分时间都是在等待 IO,而面对 CPU 密集型的任务,线程更高效。
有博友对于线程和协程总结的很好,引用其中一个观点:协程就是能保留上一次调用时的状态的过程(函数),点击阅读参考

python协程使用要点

def simple_coroutine():
    print("start")
    x = yield
    print("coroutine received:" x)
my_coro = simple_coroutine()
next(my_coro)
ouput: start
my_coro.send(99)
output:coroutine received: 99
Traceback(most recent call last):
...
StopIteration
  1. 协程使用生成器函数定义:定义体中有yield关键字;
  2. x = yield 写法表明协程只需从调用者那里接受数据,yield关键字右边没有表达式时,协程没有产出,隐式指定为None;
  3. 协程有四个状态:等待开始执行(GEN_CREATED),正在执行(GEN_RUNNING),在yield处暂停(GEN_SUSPENDED),执行结束(GEN_CLOSED),使用inspect.getgeneratorstate()可以查询当前状态;
  4. 首先需要调用next激活协程生成器my_coro,调用my_coro.send(None)作用等同于next调用,调用next后,协程函数会执行到第一个yield表达式处暂停,即处于等等开始执行状态;
  5. 调用send方法发送消息给暂停的协程,此时x为99,协程会恢复,一直运行到下一个yield处或者终止,上例中没有下一个yield,终止时按照生成器一样抛出StopIteration异常。
    上例只是表面语法级的使用规范,通常使用中会比上面复杂很多,比如协程中存储循环语句,使每次send都能执行一次yield,其次x = yield y表达式可以使协程调用者每次都能获取到结果y,另外使用yield from关键词可以免去开发者主动处理StopIteration异常,通常会用yield from构造的委派生成器连通子生成器来做实际应用。

本文主要参考《流畅的Python》

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值