利用记录型信号量解决生产者-消费者问题完整代码
时间: 2024-10-14 13:09:50 浏览: 47
生产者-消费者问题是经典的并发控制问题,涉及到生产数据(资源)和消费数据的过程。在多线程环境中,我们可以使用记录型信号量(也叫计数信号量)来协调这个过程。下面是一个使用Python的threading库和`Semaphore`来解决这个问题的简单示例:
```python
import threading
from collections import deque
import time
class Queue:
def __init__(self, capacity):
self.capacity = capacity
self.queue = deque()
self.producer_semaphore = threading.Semaphore(1) # 生产者信号量,限制同时只有一个生产者
self.consumer_semaphore = threading.Semaphore(0) # 消费者信号量,开始时不允许消费者进入,当有元素放入queue时才会唤醒
def is_empty(self):
return len(self.queue) == 0
def put(self, item):
self.queue.append(item)
with self.producer_semaphore:
if self.is_full():
time.sleep(0.1) # 阻塞一会儿,避免过度竞争
self.consumer_semaphore.release() # 唤醒一个等待的消费者
def get(self):
while True:
if not self.is_empty():
item = self.queue.popleft()
with self.consumer_semaphore:
self.producer_semaphore.acquire() # 如果有新的生产者,则释放给它
return item
time.sleep(0.1) # 当队列为空时,消费者也阻塞一段时间
def is_full(self):
return len(self.queue) >= self.capacity
# 示例
if __name__ == "__main__":
queue = Queue(3)
producers = [threading.Thread(target=enqueue_task, args=(queue, i)) for i in range(5)]
consumers = [threading.Thread(target=consume_task, args=(queue, i)) for i in range(5)]
for producer in producers:
producer.start()
for consumer in consumers:
consumer.start()
for producer in producers:
producer.join()
for consumer in consumers:
consumer.join()
```
在这个例子中,`Queue` 类包含两个信号量 `producer_semaphore` 和 `consumer_semaphore`,以及基本的入队 `put` 和出队 `get` 方法。生产者在生产数据前会获取生产者信号量,消费者在消费数据前会先检查队列是否非空并获取消费者信号量。通过这种方式,我们实现了生产者不会超过队列容量的生产,以及消费者不会在队列为空时抢夺任务的机制。
阅读全文