美文网首页Python
我要悄悄学python之生产者与消费者

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

作者: 小志Codings | 来源:发表于2021-06-14 17:20 被阅读0次

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

比如有两个进程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(1, 3))  # 模拟产生数据的时间
        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(1, 3))


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(1, 3))
        if q.empty():
            break
        print(f'{name} 消费了 {q.get()}')


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

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

生产者消费者模式特点

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

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

相关文章

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

    什么是生产者与消费者模式 比如有两个进程A与B,它们共享一个固定大小的缓冲区,A进程生产数据放入缓冲区;B进程从缓...

  • 34.Python之生产者消费者模型

    Python之生产者消费者模型(非常重要) 生产者消费者模型模型指的是一种解决问题的套路。 生产者消费者模型中包含...

  • 37.Python之生产者消费者模型

    Python之生产者消费者模型 生产者消费者模型模型指的是一种解决问题的套路,目的是为了使生产数据与处理数据达到平...

  • 2019-04-24

    基于生产者与消费者的多线程Python实现 生产者生产,消费者消费,都是针对二者共同的钱包,生产者生产的钱放入钱包...

  • 生产者-消费者问题与python Queue模块

    生产者-消费者问题与python Queue模块生产者-消费者模型是一个典型的场景,在这个场景下,商品或服务的生产...

  • 中产阶级如何保护自己的财富 2022-05-29

    本书印象最深的知识: 1.财富来自交易. 2.二阶经济学:消费者和消费者竞争,生产者与生产者竞争;生产者和消费者从...

  • 我要悄悄学Python之元组与代码格式

    元组 列表非常适用于存储在程序运行时可能变化的数据集。列表是可以修改的,然而,有时候你需要创建一系列不可修改的元素...

  • 我要悄悄学Python之文件与异常(一)

    刚刚过完清明的假期,现在周末也过完了,转眼间就是周二了。 不知道年后的这段时间里,你们是否也会有这样的感受: 身边...

  • 我要悄悄学Python之文件与异常(二)

    交心的不一定是真朋友。 遇到问题嘴上站在你身边和真正站在你身边,完全是两码事。 和别人起冲突时,沉默不语,事后才骂...

  • 我要悄悄学Python之操作列表

    前言 在上一篇文章中教会了大家如何创建了列表,还学习了如何操作列表元素。 接下来我就将上次分享给大家的内容先总结整...

网友评论

    本文标题:我要悄悄学python之生产者与消费者

    本文链接:https://www.haomeiwen.com/subject/lqsoeltx.html