#2个生产者 与 多个消费者
import time
import queue
import threading
import random
from collections import deque
# 哨兵
_sentinel = object()
_sentinel2 = object()
class Producer(threading.Thread):
"""
只负责产生数据
"""
def __init__(self, name, queue):
# python3的写法
super().__init__(name=name)
self._queue = queue
def run(self):
for i in range(5):
print("{} 正在生产产品 {} 到队列里!".format(self.getName(), i))
self._queue.put(i)
time.sleep(random.randint(1, 20) * 0.1)
# 设置完成的标志位
self._queue.put(_sentinel)
print("{}-完成".format(self.getName()))
class Producer2(Producer):
def run(self):
for i in range(65, 70):
item = chr(i)
print("{} 正在生产产品 {} 到队列里!".format(self.getName(), item))
self._queue.put(item)
time.sleep(random.randint(1, 20) * 0.8)
# 设置完成的标志位
self._queue.put(_sentinel2)
print("{}-完成".format(self.getName()))
class Consumer(threading.Thread):
"""
数据处理
"""
_deque = deque()
def __init__(self, name, queue, lock):
super().__init__(name=name)
self._queue = queue
self._lock = lock
def run(self):
while True:
value = self._queue.get(block=True, timeout=10)
# 用来退出线程
if value in (_sentinel, _sentinel2):
with self._lock:
if value not in Consumer._deque:
Consumer._deque.append(value)
self._queue.put(value)
if len(Consumer._deque) == 2:
print('Consumer._deque ==2 break')
break
else:
print("{}正在消费......{}在队列里已经被消费!".format(self.getName(), value))
print("{}完成".format(self.getName()))
if __name__ == '__main__':
q = queue.Queue()
lock = threading.Lock()
sentienl_queue = queue.Queue()
producer = Producer('生产者1', q)
producer2 = Producer2('生产者2', q)
producer2.start()
producer.start()
consumer_threads = []
for i in range(5):
consumer = Consumer('消费者_' + str(i), q, lock)
consumer_threads.append(consumer)
consumer.start()
for consumer in consumer_threads:
consumer.join()
producer.join()
producer2.join()
print('主线程已完成!')