4)协程一(yeild)

一:什么协程

协程: coroutine/coro
- 轻量级线程(一个线程)
- 调度由用户控制
- 有独立的寄存器上下文和栈
- 切换时保存状态,回来时恢复

二:协程和多线程比较

协程: coroutine/coro
- 轻量级线程(一个线程)
- 调度由用户控制
- 有独立的寄存器上下文和栈
- 切换时保存状态,回来时恢复
- 异步
- 一次调用,多个入口和结果

多进程,多线程
- 系统调度
- 上下文切换
- 占用内存
- 耗费CPU时间
- 同步
- 一次调用一次返回

三:python中协程发展

Python中协程的发展
•Python 2.5   (PEP 342) -> yield
•Python 3.3   (PEP 380) -> yield from
•Python 3.4  (PEP3156)-> asyncio
•Python 3.5   (PEP 0492).async/await 
•Eventlet
•Greenlet
•gevent

四:协程使用发展

1.协程1期:模拟阶段
- 嵌套yield的函数交互运行
- next/send(None)激活yield
- send(data)向yield发送数据
示例1
  
 1 import time
 2  
 3  
 4 def consumer():
 5     r = ''
 6     while True:
 7        n = yield  r #生成器,遇到yield就停止,并返回到porducer,等send信号,在继续向下执行,执行完了返回到yield处,并返回r
 8        if not n:
 9            return
10        print('[CONSUMR] Consuming %s' %n)
11        time.sleep(1)
12        r = '200 OK'
13 
14 
15 def produce(c):
16     next(c) #第一次调用生成器
17     n = 0
18     while n < 5:
19         n += 1
20         print('[PRODUCE] Producing %s' % n)
21         r = c.send(n) #给生成器发送数据,并把yeild返回的数据给r
22         print('[PRODUCE] Producing %s' % r,n)
23     c.close()
24  
25 
26 if __name__ == '__main__':
27     c = consumer()
28     produce(c)
协程yeild send
    # _*_ coding:utf-8 _*_
    __author__ = "lixiang"
    from inspect import getgeneratorstate
    
    #协程使用生成器函数定义:定义体中有 yield 关键字
    def simple_coro2(a):
        print("started:a=",a)
    
        b=yield a #遇到yield就停止,并把a返回给调用方
        print("received:b=",b)
        c=yield a+b ##遇到yield就停止,并把a+b返回给调用方
        print("received:c=",c)
        #协程中未处理的异常会向上冒泡,传给 next 函数或 send 方法的调用方
        #如果没有return ,生成器会返回StopIteration异常
    
    if __name__=="__main__":
    
        my_coro2=simple_coro2(14)   #与创建生成器对象。
        print(getgeneratorstate(my_coro2))  #inspect.getgeneratorstate生成器状态
        r3=next(my_coro2)   #next(my_coro2) 函数这一步通常称为“预激”(prime)协程==my_coro2.send(None)
        print(r3) #14
        print(getgeneratorstate(my_coro2))  ##inspect.getgeneratorstate生成器状态
    
        try:
            #仅当协程处于暂停状态时才能调用 send 方法,激活生成器,并绘生成器传值
            r1=my_coro2.send(28)
            print(r1) #42
    
            #生成器结束,传给 next 函数或 send 方法的调用方直接抛出异常
            r2=my_coro2.send(99)
    
            #异常未执行
            print(r2)
    
        #控制权流动到协程定义体的末尾,导致生成器像往常一样抛出 StopIteration异常
        except StopIteration as e:
            print(e)

    结果
    -----------------
    GEN_CREATED
    started:a= 14
    14
    GEN_SUSPENDED
    received:b= 28
    42
    received:c= 99
无return获取不到返回值
示例2:带return:

    # _*_ coding:utf-8 _*_
    __author__ = "lixiang"
    from inspect import getgeneratorstate
    
    #协程使用生成器函数定义:定义体中有 yield 关键字
    def simple_coro2(a):
        print("started:a=",a)
    
        b=yield a #遇到yield就停止,并把a返回给调用方
        print("received:b=",b)
        c=yield a+b ##遇到yield就停止,并把a+b返回给调用方
        print("received:c=",c)
        return c
    
    if __name__=="__main__":
    
        my_coro2=simple_coro2(14)   #与创建生成器对象。
        print(getgeneratorstate(my_coro2))  #inspect.getgeneratorstate生成器状态
        r3=next(my_coro2)   #next(my_coro2) 函数这一步通常称为“预激”(prime)协程==my_coro2.send(None)
        print(r3) #14
        print(getgeneratorstate(my_coro2))  ##inspect.getgeneratorstate生成器状态
    
        try:
            #仅当协程处于暂停状态时才能调用 send 方法,激活生成器,并绘生成器传值
            r1=my_coro2.send(28)
            print(r1) #42
    
            #生成器结束,直接抛出异常
            my_coro2.send(99)
    
        #控制权流动到协程定义体的末尾,导致生成器像往常一样抛出 StopIteration异常
        except StopIteration as e:
            print(e)#获取return返回值

    结果:---------
    GEN_CREATED
    started:a= 14
    14
    GEN_SUSPENDED
    received:b= 28
    42
    received:c= 99
    99
带return,获取返回值

 

 

posted on 2018-07-16 20:47  shisanjun  阅读(168)  评论(0)    收藏  举报

导航