生产者、消费者问题,python实现

本文介绍了一个经典的线程同步问题——生产者消费者模型的Python实现。通过使用锁对象确保线程安全,实现生产者向缓冲池放入产品,消费者从中取出产品的过程。代码示例展示了如何在多线程环境下控制缓冲池的状态。

      生产者、消费者问题,经典的线程同步问题:假设有一个缓冲池(列表),生产者往里面放东西,消费者从里面取,规则是:列表为空的时候,生产者才能放东西;列表不为空的时候,消费者才能取东西;为了简单起见,暂定缓冲池中最多只能有一个产品。这里生产者和消费者共同操作一个资源:缓冲池,因此每次操作的时候,需要给资源加锁,操作结束时,释放锁,这样才能做到资源同步。使用python实现,需要继承Thread类,获取锁对象,代码如下:

from threading import Thread
from threading import Lock
import time,random

pro_list = []
lock = Lock()

class Producer(Thread):
    def run(self):
        global pro_list
        while True:
            i = random.randint(0, 100)
            lock.acquire()
            if len(pro_list) > 0:
                print "!--product still in list, wait consumer to get it.."
            else:
                pro_list.append(i)
                print ":::Producer put:", pro_list[0]
            lock.release()
            time.sleep(2)

class Consumer(Thread):
    def run(self):
        global pro_list
        while True:
            lock.acquire()
            if len(pro_list) == 0:
                print "!--No product now, wait producer put in..."
            else:
                print ":::Consumer fetch:", pro_list[0]
                pro_list.pop(0)
            lock.release()
            time.sleep(2)

Producer().start()
Producer().start()
Consumer().start()
Producer().start()
Producer().start()
Consumer().start()
Consumer().start()

这里使用多个生产者和消费者,共同操作缓冲池,部分执行结果如下:

:::Producer put: 12
!--product still in list, wait consumer to get it..
:::Consumer fetch: 12
:::Producer put: 75
!--product still in list, wait consumer to get it..
:::Consumer fetch: 75
!--No product now, wait producer put in...
:::Producer put: 28
!--product still in list, wait consumer to get it..
!--product still in list, wait consumer to get it..
:::Consumer fetch: 28
:::Producer put: 94
:::Consumer fetch: 94

### 使用Python实现生产者消费者模型 以下是使用`queue.Queue`和多线程来实现生产者消费者模型的一个简单示例: ```python import threading import time import random from queue import Queue # 定义缓冲区大小 BUFFER_SIZE = 5 # 创建队列作为共享缓冲区 buffer_queue = Queue(BUFFER_SIZE) def producer(buffer, event): """生产者函数""" count = 0 while True: item = f"Item-{count}" if buffer.full(): print(f"[Producer] Buffer is full. Waiting... {item}") event.wait() # 如果缓冲区满了,则等待消费者的信号 event.clear() print(f"[Producer] Producing {item}...") buffer.put(item) print(f"[Producer] Added to buffer: {item}. Current size: {buffer.qsize()}") count += 1 time.sleep(random.uniform(0.5, 1)) # 随机延迟模拟生产时间 def consumer(buffer, event): """消费者函数""" while True: if buffer.empty(): print("[Consumer] Buffer is empty. Notifying producers...") event.set() # 缓冲区为空时通知生产者继续工作 continue item = buffer.get() print(f"[Consumer] Consuming {item}...") print(f"[Consumer] Removed from buffer: {item}. Current size: {buffer.qsize()}") time.sleep(random.uniform(1, 2)) # 随机延迟模拟消费时间 if __name__ == "__main__": # 创建事件对象用于线程间通信 event = threading.Event() # 启动生产者消费者线程 producer_thread = threading.Thread(target=producer, args=(buffer_queue, event)) consumer_thread = threading.Thread(target=consumer, args=(buffer_queue, event)) producer_thread.daemon = True consumer_thread.daemon = True producer_thread.start() consumer_thread.start() # 主线程保持运行状态 try: while True: time.sleep(1) except KeyboardInterrupt: print("Program terminated by user.") ``` 上述代码展示了如何通过`threading`模块创建多个线程,并使用`Queue`类管理生产和消费的过程[^1]。 如果希望采用异步编程的方式实现生产者消费者模型,可以借助`asyncio`库完成。下面是一个基于`asyncio`的实现示例: ```python import asyncio import random # 设置缓冲区容量 BUFFER_LIMIT = 5 async def producer(queue): """异步生产者函数""" count = 0 while True: item = f"Product-{count}" await queue.put(item) print(f"[Producer] Produced {item}, current queue size: {queue.qsize()}") if queue.qsize() >= BUFFER_LIMIT: print("[Producer] Buffer limit reached! Pausing production...") await asyncio.sleep(random.uniform(1, 3)) # 模拟暂停生产 count += 1 await asyncio.sleep(random.uniform(0.5, 1)) # 控制生产速度 async def consumer(queue): """异步消费者函数""" while True: item = await queue.get() print(f"[Consumer] Consumed {item}, current queue size: {queue.qsize()}") queue.task_done() await asyncio.sleep(random.uniform(1, 2)) # 控制消费速度 async def main(): """主协程函数""" queue = asyncio.Queue(maxsize=BUFFER_LIMIT) tasks = [ asyncio.create_task(producer(queue)), asyncio.create_task(consumer(queue)) ] await asyncio.gather(*tasks) if __name__ == "__main__": asyncio.run(main()) ``` 此代码片段展示了一个基于`asyncio`的生产者消费者模型,其中生产者消费者分别以独立的任务形式存在,并通过`asyncio.Queue`进行交互[^2]。 #### 关键点说明 - `queue.Queue`适用于传统的多线程环境下的生产者消费者问题。 - 对于高并发场景或者需要非阻塞操作的情况,推荐使用`asyncio.Queue`配合异步IO技术[^3]。 - 当缓冲区达到上限或下限时,可以通过条件变量或其他同步机制控制生产者消费者的执行节奏[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值