队列queue
- 队列用于线程之间安全的信息交换
- 队列和列表的区别:队列里的信息get()后就没了,而列表获取数据则是copy,原列表里的值还在
使用前先实例化队列
q = queue.Queue(maxsize=0)
#先入先出,默认队列大小无限制q = queue.LifoQueue(maxsize=0)
#后入先出q = queue.PriorityQueue(maxsize=0)
#存储数据时可设置优先级的队列- 使用此类型队列时,put入一个元组,按元组的第一个值排序
- put((2,'lmc')),put((-1,'pwd')),数字排序,越小的先出,这里第一次get()将获得(-1,'pwd')
- put(('linux','ubuntu')),put(('apple','mac')),字符串排序,a<l,这里第一次get()将获得('apple','mac')
使用q.put(item)
存入信息
- put('a str')
- put(1)
使用q.get()
取出信息
- get()会根据q实例化的类型取出信息(queue.Queue,先取出的是“a str”,LifoQueue先取出的则是1
- get()时,如果超过put()入队列数量(qsize()),则会挂起等待下一个put()后继续执行
Queue.put_nowait(item)等价于 put(item, False)
- 如果设置队列最大上限maxsize,put()时超过最大上限,则会挂起等待下一个get()取出信息后执行
- 使用put_nowait()如果超过上限,则会抛出错误,不会挂起
Queue.get_nowait()等价于Queue.get(block=True, timeout=None)
- 使用get_nowait()如果超过put()数量,即队列里没信息了,不会挂起,会抛出错误
其他方法
- Queue.qsize() 队列当前大小
- Queue.empty() #如果队列为空返回True
- Queue.full() # 如果队列已满返回True,前提已设置了maxsize
生产者消费者模型
-
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。
-
为什么要使用生产者和消费者模式
-
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。
-
什么是生产者消费者模式
-
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
-
基本的一个例子
import threading
import queue
def producer():
for i in range(10):
q.put("骨头 %s" % i )
print("开始等待所有的骨头被取走...")
q.join()
print("所有的骨头被取完了...")
def consumer(n):
while q.qsize() >0:
print("%s 取到" %n , q.get())
q.task_done() #告知这个任务执行完了
q = queue.Queue()
p = threading.Thread(target=producer,)
p.start()
c1 = consumer("李闯")