我要悄悄学python之生产者与消费者

什么是生产者与消费者模式

比如有两个进程A与B,它们共享一个固定大小的缓冲区,A进程生产数据放入缓冲区;B进程从缓冲区取出数据进行计算,那么这里的A进程就相当于生产者,B进程相当于消费者。

为什么要使用生产者与消费者模式

在进程的世界里,生产者就是生产数据的进程,消费者就是使用(处理)数据的进程。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。同样的道理,如果生产者的处理能力大于消费者能力,那么生产者就必须等待消费者。

实现了生产者与消费者的解耦和,平衡了生产力与消费力,因为二者不能直接沟通,而是通过队列进行沟通。

生产者消费者模式

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。

生产者与消费者不直接通信,而是通过阻塞队列进行通信,因此,生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是去阻塞队列中找数据。阻塞队列就类似于缓冲区,平衡了生产者与消费者的能力。

multiprocess-Queue实现

具体代码,如下所示:

from multiprocessing import Process, Queue
import time, random
from threading import Thread
import queue


# 生产者
def producer(name, food, q):
    for i in range(4):
        time.sleep(random.randint(13))  # 模拟产生数据的时间
        f = '%s 生产了 %s %s个' % (name, food, i + 1)
        print(f)
        q.put(f)


# 消费者
def consumer(name, q):
    while True:
        food = q.get()
        if food is None:
            print('%s 获取到一个空' % name)
            break
        f = '%s 消费了 %s' % (name, food)
        print(f)
        time.sleep(random.randint(13))


if __name__ == '__main__':
    q = Queue()  # 创建队列
    # 模拟生产者,产生数据
    p1 = Process(target=producer, args=('p1''包子', q))
    p1.start()
    p2 = Process(target=producer, args=('p2''烧饼', q))
    p2.start()

    c1 = Process(target=consumer, args=('c1', q))
    c1.start()
    c2 = Process(target=consumer, args=('c2', q))
    c2.start()

    p1.join()
    p2.join()
    q.put(None)
    q.put(None)

Thread-Queue实现

上面的代码是由多进程实现的,接下来就考虑一下多线程实现该功能。

具体代码,如下所示:

import random
import time
from threading import Thread
import queue


def producer(name, count, q):
    for i in range(count):
        food = f'{name} 生产第{i}个包子'
        print(food)
        q.put(food)


def consumer(name, q):
    while True:
        time.sleep(random.randint(13))
        if q.empty():
            break
        print(f'{name} 消费了 {q.get()}')


if __name__ == '__main__':
    q = queue.Queue()
    print(q.empty())
    for i in range(14):
        p = Thread(target=producer, args=(f'生产者{i}'10, q))
        p.start()

    for i in range(16):
        c = Thread(target=consumer, args=(f'消费者{i}', q))
        c.start()

生产者消费者模式特点

  • 保证生产者不会在缓冲区满的时候继续向缓冲区放入数据,而消费者也不会在缓冲区空的时候,消耗数据。

  • 当缓冲区满的时候,生产者会进入休眠状态,当下次消费者开始消耗缓冲区数据时,生产者才会被唤醒,开始往缓冲区添加数据;当缓冲区空的时候,消费者会进入休眠状态,直到生产者往缓冲区添加数据时才会被唤醒。


原文始发于微信公众号(小志Codings):我要悄悄学python之生产者与消费者

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/236609.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!