Python学习笔记:队列、生产者消费者模型
一:队列(Queue):
1、定义:队列可以理解成一个容器,这个容器内部是有顺序的,类似于链表和堆栈,队列也是存储数据的结构。队列中数据进入队列的顺序很重要,一般来说,队列就是一群人或者事物按照排好的顺序等待接受服务或者处理
2、作用:
a、程序之间的解耦(降低代码依赖度):假如是在前端后端之间加入队列,那么前端只需要将数据丢到队列中,并不需要关心后端怎么生成数据的,前端用户数量的扩展也与后端无关,后端数据处理能力的扩展也与前端无关。
b、提高程序执行效率:前端无需等待后端执行完毕,只需要将数据放到队列中,队列自行执行,这期间就可以去干别的事情,回头来取结果即可。
3、队列和列表的区别?
有列表为什么还要队列呢?列表也可以当成一个容器来用,区别就在于列表数据取出相当于复制一份取出,除非手动删除这个数据,不然还依然会在列表中,而队列则取走一个就自动删除了。
4、队列代码:
import queue import queue # 带优先级的队列,数字越小,优先级越高 q = queue.PriorityQueue() q.put((-1, "car1")) q.put((3, "car2")) q.put((10, "car3")) q.put((6, "car4")) print(q.get()) print(q.get()) print(q.get()) print(q.get()) # 先进先去 q = queue.Queue() q.put("1") q.put("2") q.put("3") print(q.get()) print(q.get()) print(q.get()) # 后进先出,生活中也有这种例子,比如买水果,肯定是买先进的新鲜的水果 q = queue.LifoQueue() q.put(1) q.put(2) q.put(3) print(q.get()) print(q.get()) print(q.get()) # 如果get的次数已经超过了队列中元素的数量,那么程序就会进入等待,等待队列中新的元素进入(需要另外一个线程添加元素), # 如果不想程序进入等待,可以用get_nowait或者get(block=False),如果队列为空会抛出Empty异常,或者判断队列元素empty则不get if not q.empty(): print("从队列中拿出元素:", q.get()) # print("...1",q.get(block=False)) # print("...2",q.get_nowait())
二、生产者消费者模型:
1、定义:此模型通过一个容器来解决数据生成者和消费者之间的强耦合问题,生成者和消费者之间不直接通信,而通过阻塞队列来通信,生成者生成数据以后不需要等消费者,只需将数据放到队列中,消费者也不直接找生产者要数据,而是直接到队列中取,队列相当于一个缓冲区,平衡生产和消费者的处理能力。
# 生产消费模型 import queue import threading import time # 生产了10个以后,生产线程阻塞,只有消费者消费了一个以后才会继续生产 q = queue.Queue(maxsize=10) # 生产者 def Producer(name): count = 1 while True: q.put("骨头%s" % count) print(" 一共生产了骨头:%s" % count," 目前队列有:%s" % q.qsize()) count += 1 # 生产的越快,吃的越快 time.sleep(0.1) # 消费者 def Consumer(name): # while q.qsize()>0: while True: print(" [%s] 取到[%s] 并且吃了它..." % (name, q.get())) time.sleep(1) p = threading.Thread(target=Producer, args=("生产者1",)) c = threading.Thread(target=Consumer, args=("用户1",)) c1 = threading.Thread(target=Consumer, args=("用户2",)) p.start() c.start() c1.start()