码迷,mamicode.com
首页 > 编程语言 > 详细

玩转python(6)协程

时间:2018-05-31 19:29:09      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:就是   数据   并且   inpu   拉取   亮点   如何   code   用户   

多任务系统一般都需要解决一个问题:多个任务如何调度。抢占式调度就是一种很常见的任务调度机制。以单核模式下的进程调度为例,一个进程处于运行状态,其他的处于就绪队列,等到当前运行的进程放弃CPU的使用权,系统将CPU立刻分配给新到达的进程,由于任务的执行顺序是不确定的,看上去就像一堆任务在竞争CPU的使用权,所以这种多任务运行方式叫做“多任务竞争”。与之对应的是非抢占式调度。当前任务会持续执行下去直到因为某些原因主动放弃CPU的使用权,各个任务的执行顺序是确定的,就像在互相协作,所以这种多任务运行方式也叫做“多任务协作”。协程就是一种典型的多任务协作解决方案。协程是指一个过程,这个过程与调用方协作,产出由调用方提供的值。它的运行流程大致如下:

  1. 协程A开始执行。
  2. 协程A执行到某一步,暂停执行,执行权转移到协程B。
  3. 协程B执行一段时间后交还执行权。
  4. 协程A恢复执行。

那么生成器是如何与协程扯上关系的呢?在一个生成器中,yield item这行代码会产出一个值,提供给next()的调用方;此外,还会作出让步,暂停执行生成器,让调用方继续工作,直到需要使用另一个值时再调用next()。调用方会从生成器中拉取值。如果只能产出值,生成器显然用处不大。在python2.5之后的版本中,生成器API 中增加了send()方法。生成器的调用方可以使用send()方法发送数据,发送的数据会成为生成器函数中yield表达式的值。这样生成器既能接收数据,又能产出数据,可以作为协程使用。下面是一个简单的协程实例:

def fun():
    r = ‘‘
    while True:
        n = yield r
        if not n:
            return
        print(‘fun test %s...‘ % n)
        r = ‘200 OK‘

协程在执行到n = yield r这个表达式时,首先输出r,然后将接收到的数据赋给n。然后向下执行直到遇到下一个yield语句,循环往复。接下来我们来看看这个协程是怎么工作的~

c = fun()
next(c)
c.send(‘1‘)

测试结果如下:

input:1

尽管fun()中有一个死循环,但是遇到yield,协程就会让出执行权。而且协程有个亮点,它没有涉及到上下文切换,所有的过程都是在用户空间进行的,协程的创建开销也很小,所以完全没有创建线程时的各种考虑。因此如果有多个任务,并且我们知道如何安排任务协作的情况下,协程无疑是一个好选择。

玩转python(6)协程

标签:就是   数据   并且   inpu   拉取   亮点   如何   code   用户   

原文地址:https://www.cnblogs.com/bugsheep/p/9117688.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!