使用Python实现生产者消费者问题

本文介绍了一个使用Python实现的生产者消费者模式案例。该案例通过线程间的同步与互斥机制来确保队列的安全操作,队列容量限定为5。文中详细展示了如何创建生产者与消费者线程,并通过车间类来组织多个生产者与消费者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前用C++写过一篇生产者消费者的实现。

生产者和消费者主要是处理互斥和同步的问题:

队列作为缓冲区,需要互斥操作

队列中没有产品,消费者需要等待,直到生产者放入产品并通知它。队列慢的情况类似。

这里我使用list模拟Python标准库的Queue,这里我设置一个大小限制为5:

SyncQueue.py

from threading import Lock
from threading import Condition
class Queue():
    def __init__(self):
        self.mutex = Lock()
        self.full = Condition(self.mutex)
        self.empty = Condition(self.mutex)
        self.data = []

    def push(self, element):
        self.mutex.acquire()
        while len(self.data) >= 5:
            self.empty.wait()
            
        self.data.append(element)
        self.full.notify()    
        self.mutex.release()


    def pop(self):
        self.mutex.acquire()
        while len(self.data) == 0:
            self.full.wait()
        data = self.data[0]
        self.data.pop(0)
        self.empty.notify()
        self.mutex.release()

        return data

if __name__ == '__main__':
    q = Queue()
    q.push(10)
    q.push(2)
    q.push(13)

    print q.pop()
    print q.pop()
    print q.pop()

这是最核心的代码,注意里面判断条件要使用while循环。

接下来是生产者进程,producer.py

from threading import Thread
from random import randrange
from time import sleep
from SyncQueue import Queue

class ProducerThread(Thread):
    def __init__(self, queue):
        Thread.__init__(self)
        self.queue = queue
    def run(self):
        while True:
            data = randrange(0, 100)
            self.queue.push(data)
            print 'push %d' % (data)
            sleep(1)

if __name__ == '__main__':
    q = Queue()
    t = ProducerThread(q)
    t.start()
    t.join()

消费者,Condumer.py

from threading import Thread
from time import sleep
from SyncQueue import Queue

class ConsumerThread(Thread):
    def __init__(self, queue):
        Thread.__init__(self)
        self.queue = queue
    def run(self):
        while True:
            data = self.queue.pop()
            print 'pop %d' % (data)
            sleep(1)

if __name__ == '__main__':
    q = Queue()
    t = ConsumerThread(q)
    t.start()
    t.join()

最后我们写一个车间类,可以指定线程数量:

from SyncQueue import Queue
from Producer import ProducerThread
from Consumer import ConsumerThread

class WorkShop():
    def __init__(self, producerNums, consumerNums):
        self.producers = []
        self.consumers = []
        self.queue = Queue()
        self.producerNums = producerNums
        self.consumerNums = consumerNums
    def start(self):
        for i in range(self.producerNums):
            self.producers.append(ProducerThread(self.queue))
        for i in range(self.consumerNums):
            self.consumers.append(ConsumerThread(self.queue))
        for i in range(len(self.producers)):
            self.producers[i].start()
        for i in range(len(self.consumers)):
            self.consumers[i].start()
        for i in range(len(self.producers)):
            self.producers[i].join()
        for i in range(len(self.consumers)):
            self.consumers[i].join()

if __name__ == '__main__':
    w = WorkShop(3, 4)
    w.start()

最后写一个main模块:

from WorkShop import WorkShop

if __name__ == '__main__':
    w = WorkShop(2, 3)
    w.start()

转载于:https://www.cnblogs.com/inevermore/p/4189958.html

Python中,可以使用`gevent`库来实现生产者消费者问题,这是一种经典的问题,用于模拟并发环境下的数据交换,比如消息队列模型。`gevent`提供了一种轻量级的事件循环机制,使得我们可以轻松地处理I/O阻塞。 下面是一个简单的生产者消费者示例: ```python from gevent import monkey, sleep, Greenlet import random # 禁止全局猴子补丁,防止干扰其他模块 monkey.patch_all() # 生产者 class Producer(Greenlet): def __init__(self, queue): super().__init__() self.queue = queue def run(self): while True: item = 'Item ' + str(random.randint(0, 9)) self.queue.put(item) print(f"Produced {item}") sleep(random.random()) # 消费者 class Consumer(Greenlet): def __init__(self, queue): super().__init__() self.queue = queue def run(self): while True: if not self.queue.empty(): item = self.queue.get() print(f"Eaten {item}") sleep(random.random()) else: print("Queue is empty.") queue = GreenletQueue() producer = Producer(queue) consumer = Consumer(queue) producer.start() # 启动生产者 consumer.start() # 同时启动消费者 # 等待一段时间后结束 sleep(5) producer.kill() # 结束生产者,停止生成新元素 consumer.join() # 确保消费者消费完所有元素再退出 ``` 在这个例子中,`Producer`负责生成物品放入队列,而`Consumer`从队列中取出并消费它们。通过`gevent`的异步特性,我们可以在一个线程中同时运行生产者消费者,避免了同步阻塞。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值