Python 生产者消费者模型

Python 生产者消费者模型

生产者消费者模型介绍

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

生产者指的是生产数据的任务,消费者指的是处理数据的任务,在并发编程中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

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

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

生产者消费者模型实现

函数yield 方式

def producer(name, count, cons):
    cons.send(None)
    for i in range(count):
        print(f"{name}, 生产了第{i}个包子")
        cons.send(f"{name}, 第{i}个包子")


def consumer(name):
    while True:
        time.sleep(1)
        n = yield
        print(f"\033[1;32m{name} 吃了{n}\033[0m")


for i in range(1, 3):
    c = consumer(f"消费者{i}")
    producer(f"生产者{i}", 5, c)

多进程方式

实现一、

使用多进程+多进程模块中的Queue队列实现

import time
from multiprocessing import Process, Queue


def producer(name, q, count):
    for i in range(count):
        time.sleep(0.5)
        d = f"生产者{name} 第{i}包子"
        print(d)
        q.put(d)


def consumer(name, q):
    while True:
        time.sleep(1)
        if q.empty():   # 判断队列是否为空, 为空结束索取
            break
        print(f"\033[1;32m消费者{name} 吃了{q.get()}\033[0m")


if __name__ == '__main__':
    queue = Queue()
    for i in range(1, 3):
        p = Process(target=producer, args=(i, queue, 10))
        p.start()

    for i in range(1, 6):
        c = Process(target=consumer, args=(i, queue))
        c.start()

    print("主进程")
实现二、

使用多进程+多进程模块中的JoinableQueue队列实现

import time
from multiprocessing import Process, JoinableQueue


def producer(name, q, count):
    for i in range(count):
        time.sleep(0.5)
        d = f"生产者{name} 第{i}包子"
        print(d)
        q.put(d)
    q.join()


def consumer(name, q):
    while True:
        time.sleep(1)
        print(f"\033[1;32m消费者{name} 吃了{q.get()}\033[0m")
        q.task_done()


if __name__ == '__main__':
    queue = JoinableQueue()
    p_list = []
    for i in range(1, 3):
        p = Process(target=producer, args=(i, queue, 10))
        p_list.append(p)
        p.start()

    for i in range(1, 6):
        c = Process(target=consumer, args=(i, queue))
        c.daemon = True
        c.start()

    for i in p_list:
        i.join()

    print("主进程")

多线程方式

queue 模块实现了多生产者、多消费者队列。这特别适用于消息必须安全地在多线程间交换的线程编程

def producer(name, count, q):
    for i in range(count):
        i = f"{name} 第{i}包子"
        print(i)
        q.put(i)


def consumer(name, q):
    while True:
        time.sleep(0.5)
        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()

    print("主进程")
生产者消费者模型是一种经典的并发编程模型,用于解决生产者和消费者之间的数据交换问题。在 Python 中,可以使用多线程多进程实现生产者消费者模型。 下面是一个使用 Python 多线程实现生产者消费者模型的示例代码: ```python import threading import queue import time # 定义一个线程安全的队列 q = queue.Queue(maxsize=10) # 定义一个生产者线程 class Producer(threading.Thread): def run(self): while True: # 如果队列未满,则向队列中添加数据 if not q.full(): item = time.strftime('%H:%M:%S', time.localtime()) q.put(item) print(f'生产者 {self.name} 生产了 {item}') time.sleep(1) # 定义一个消费者线程 class Consumer(threading.Thread): def run(self): while True: # 如果队列不为空,则从队列中取出数据 if not q.empty(): item = q.get() print(f'消费者 {self.name} 消费了 {item}') time.sleep(2) if __name__ == '__main__': # 创建两个生产者线程和三个消费者线程 producers = [Producer() for i in range(2)] consumers = [Consumer() for i in range(3)] # 启动所有线程 for p in producers: p.start() for c in consumers: c.start() # 等待所有线程结束 for p in producers: p.join() for c in consumers: c.join() ``` 在上面的代码中,我们定义了一个线程安全的队列 `q`,并定义了一个生产者线程 `Producer` 和一个消费者线程 `Consumer`。生产者线程不断向队列中添加数据,消费者线程不断从队列中取出数据。我们创建了两个生产者线程和三个消费者线程,并启动所有线程。最后,我们使用 `join()` 方法等待所有线程执行完毕。运行上面的代码,可以看到生产者不断生产数据,消费者不断消费数据,实现了生产者消费者模型
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值