zoukankan      html  css  js  c++  java
  • 关于Python的协程问题总结

    协程其实就是可以由程序自主控制的线程

    在python里主要由yield 和yield from 控制,可以通过生成者消费者例子来理解协程

    利用yield from 向生成器(协程)传送数据
    # 传统的生产者-消费者是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。
    # 如果改用协程,生产者生产消息后,直接通过yield跳转到消费者开始执行,待消费者执行完毕后,换回生产者继续生产,效率极高
    def consumer():
        r = ''
        while True:
            n = yield r
            if not n:
                return
            print('[CONSUMER] Consuming %s...' % n)
            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()
    
    c = consumer()
    produce(c)
    # 注意到consumer函数是一个generator,把一个consumer传入produce后:
    # 首先调用c.send(None)启动生成器;
    # 然后,一旦生产了东西,通过c.send(n)切换到consumer执行;
    # consumer通过yield拿到消息,处理,又通过yield把结果传回;
    # produce拿到consumer处理的结果,继续生产下一条消息;
    # produce决定不生产了,通过c.close()关闭consumer,整个过程结束。
    # 整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。
    # 最后套用Donald Knuth的一句话总结协程的特点:
    # “子程序就是协程的一种特例。”

    理解上面的例子对python的协程理解很重要

    下面是Python3.4支持协程的写法

    import threading
    import asyncio
    @asyncio.coroutine
    def hello(s):
        print(s)
        print('Hello world! (%s)' % threading.currentThread())
        yield from asyncio.sleep(1)
        print(s)
        print('Hello again! (%s)' % threading.currentThread())
    
    loop = asyncio.get_event_loop()
    tasks = [hello('w'), hello('e')]
    loop.run_until_complete(hello('o'))
    # 添加到task 表示一起执行
    loop.run_until_complete(asyncio.wait(tasks))
    tasks2 = [hello('w'), hello('e'),hello('H')]
    print('++++++++++++++++++++')
    loop.run_until_complete(asyncio.wait(tasks2))
    loop.close()
    # 由一个线程通过coroutine并发完成。
    # async和await是针对coroutine的新语法,要使用新的语法,只需要做两步简单的替换:
    # 把@asyncio.coroutine替换为async;
    # 把yield from替换为await。
    # 注意新语法只能用在Python 3.5以及后续版本,如果使用3.4版本,则仍需使用上一节的方案。
    import asyncio
    async def hello():
        print("Hello world!")
        r = await asyncio.sleep(1)
        print("Hello again!")
    loop=asyncio.get_event_loop()
    loop.run_until_complete(hello())
  • 相关阅读:
    MC9S12 硬件设计
    ESD
    选用与使用稳压二极管的介绍
    MOSFET 栅极电阻作用及其选型
    orcad常用库文件介绍
    开关电源和LDO的区别
    续流二极管的作用及选型
    为什么大电容滤低频小电容滤高频的问题
    Java常用API——时间类
    Idea问题:“marketplace plugins are not loaded”解决方案
  • 原文地址:https://www.cnblogs.com/qieyu/p/9242678.html
Copyright © 2011-2022 走看看