要求:
-
get 使用多线程实现有1个生产者生产消息,但有2个消费者同时在消费消息。
-
get 生产者产生的消息都需要先存放到一个缓冲池中(用列表代替),然后再由消费者从这个缓冲池取消息消费。
-
get 缓冲池最多只能存放5个消息,如果超过这个大小,生产者需要等待缓冲池,可以继续存放消息后再进行存放,但是在等待的过程中不能停止生产消息。
-
get 生产者每秒生产1个消息,总共生产10个消息,这10个消息分别用数字1~10表示
-
get 生产者在所有消息成功,发送到缓冲区之后需要退出。
-
get 消费者每隔2秒尝试获取一个最早的消息处理,
-
get 消费者每次消息处理耗时5秒
-
get 如果消费者连续在10秒之内获取不到任何消息后需要退出。
-
get 每个消息只允许被任意1个消费者处理一次。
-
get 若无消费者,生产者在生产完毕后退出
解题代码:
import time
import threading
mutex = threading.Lock()
# 第 4 条
task = list(range(1, 11))
# 第 2 条
queue = []
consumer_l = list()
# 生产者类
class Producer(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self, name=name)
def run(self):
tmp_task = list()
while True:
# 第 5 条
if not len(task) and not len(tmp_task):
break
if not len(task):
# tmp_task 存在未推入缓冲池消息
if len(queue) == 5:
# 第 10 条
if not len(consumer_l):
break
continue
queue.append(tmp_task.pop(0))
else:
sig_task = task.pop(0)
print("生产{}".format(sig_task))
# 第 3 条
if len(queue) == 5:
tmp_task.append(sig_task)
else:
if tmp_task:
queue.append(tmp_task.pop(0))
else:
queue.append(sig_task)
# 第 4 条
time.sleep(1)
print("%s finished!" % self.getName())
# 消费者类
class Consumer(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self, name=name)
def run(self):
global mutex
count = 0
while True:
# 第 8 条
if count > 10:
print("{} 超时,断开连接..".format(self.getName(), ))
consumer_l.remove(self.getName())
break
# 第 6 条
if not len(queue):
count += 1
print("{} 未获取到信息,2秒后重新获取..".format(self.getName(), ))
time.sleep(2)
continue
count = 0
# 第 9 条
mutex.acquire()
sig_task = queue.pop(0)
mutex.release()
print("{} 获取信息 {}".format(self.getName(), sig_task))
# 第 7 条
time.sleep(5)
print("{} 消费 {}".format(self.getName(), sig_task))
print("%s finished!" % self.getName())
def main():
global consumer_l
consumer_1 = Consumer('Consumer_1')
consumer_2 = Consumer('Consumer_2')
consumer_l.extend([consumer_1.name, consumer_2.name])
producer = Producer('Producer')
# 第 1 条
producer.start()
consumer_1.start()
consumer_2.start()
producer.join()
consumer_1.join()
consumer_2.join()
print('All threads finished!')
def main2():
"""
只存在生产者
:return:
"""
producer = Producer('Producer')
producer.start()
producer.join()
print('All threads finished!')
if __name__ == '__main__':
main()