• python通过生成器实现协程-生产消费者模型


    Python对协程的支持是通过generator实现的。
    在generator中,我们不但可以通过 for 循环来迭代,还可以不断调用 next() 函
    数获取由 yield 语句返回的下一个值。
    但是Python的 yield 不但可以返回一个值,它还可以接收调用者发出的参数。
    传统的生产者-消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队
    列和等待,但一不小心就可能死锁。
    如果改用协程,生产者生产消息后,直接通过 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)  ##next(c)
        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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    输出:

    [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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

    1. 首先调用 c.send(None) 启动生成器;
    2. 然后,一旦生产了东西,通过 c.send(n) 切换到 consumer 执行;
    3. consumer 通过 yield 拿到消息,处理,又通过 yield 把结果传回;
    4. produce 拿到 consumer 处理的结果,继续生产下一条消息;
    5. produce 决定不生产了,通过 c.close() 关闭 consumer ,整个过程结
      束。
      整个流程无锁,由一个线程执行, produce 和 consumer 协作完成任务,所以称
      为“协程”,而非线程的抢占式多任务。
  • 相关阅读:
    9.20 作业
    九、【漏洞复现】Struts 2 远程代码执行漏洞s2-046(CVE-2017-5638)
    笔记 | 非素数个数(朴素筛查 || 埃式筛查法)
    香港科技大学广州|可持续能源与环境学域博士招生宣讲会—广州大学城专场!!!(暨全额奖学金政策)
    Win11右键恢复Win10老版本
    AI全栈大模型工程师(三)GPT 能干什么?
    css正确的语法
    (g6)Radial 辐射布局
    顺序表详解——遍历、增添、查找、删除、修改、清除
    PHP+MySQL制作简单动态网站(附详细注释+源码)
  • 原文地址:https://blog.csdn.net/rockstics/article/details/125570415