queue
queue模块中提供了同步的、线程安全的队列类。这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的同步
导入以下模块:
from queue import Queue, LifoQueue, PriorityQueue
一、Queue:FIFO先进先出队列Queue
q = Queue() # 创建一个队列
q.put('python') # 队列添加数据
q.put('java') # 队列添加数据
print(q.get()) # 获取队列中的数据
print(q.get()) # 获取队列中的数据
print(q.qsize()) # 获取队列长度
>>> python
>>> java
>>> 2
创建队列时指定队列长度:maxsize,默认为0不限长度
q = Queue(3) # 指定队列长度,只能放3个数据
q.put('python') # 队列添加数据
q.put('java') # 队列添加数据
q.put('python1') # 队列添加数据
print("队列已满")
队列默认是堵塞的,当队列满了以后程序就会处于等待状态,如下:
q.put('java2') # 队列添加数据
如不等待则需要在添加数据时通过timeout参数指定等待时间:
q = Queue(2) # 创建一个队列
q.put('python') # 队列添加数据
q.put('java') # 队列添加数据
print("队列已满")
q.put('java',timeout=2) # 队列满了以后等待2秒后抛出异常
>File "D:\python39\lib\queue.py", line 148, in put
raise Full
queue.Full
同理当数据获取完以后,继续获取也会进入堵塞,也可以指定timeout参数等待时间,如下:
q = Queue(2) # 创建一个队列
q.put('python') # 队列添加数据
q.put('java') # 队列添加数据
print("队列已满")
print(q.get()) # 获取队列中的数据
print(q.get()) # 获取队列中的数据
print("数据已获取完")
print(q.get(timeout=2)) # 队列为空后等待2秒抛出异常
此外还有两种方法可以在添加或获取时默认为不等待,直接抛异常:
q.put_nowait("python1") # 队列满了以后直接抛异常
q.get_nowait() # 队列空了以后直接抛异常
判断队列是否为空/已满:
q.empty() # 判断是否为空
q.full() # 判断是否已满
task_done()与join():
当获取完队列中的数据后,由task_done向队列发送一条任务执行完毕的消息,而join()时一直阻塞直到队列中的所有项目都已获取并处理完毕。
如下,获取一次数据就需要告诉队列执行完毕的消息。这时候获取了两条数据task_done了一次,所以join()会一直堵塞。
q = Queue(2) # 创建一个队列
q.put('python') # 队列添加数据
q.put('java')
print(q.get()) # 获取队列中的数据
print(q.get())
q.task_done()
#q.task_done()
q.join()
剩下两种队列类型与Queue方法使用都一致,只是数据的出与入的机制不一样而已。
二、LifoQueue:LIFO(后入先出)队列LifoQueue
q = LifoQueue(2) # 创建一个队列
q.put('python') # 队列添加数据
q.put('java') # 队列添加数据
print(q.qsize()) # 获取队列长度
print(q.get()) # 获取队列中的数据
print(q.get()) # 获取队列中的数据
q.task_done()
q.task_done()
q.join()
>>> 2
>>> java
>>> python
三、PriorityQueue:优先级队列PriorityQueue
q = PriorityQueue(3) # 创建一个队列
# 队列添加数据
q.put(1)
q.put(4)
q.put(3)
print(q.qsize()) # 获取队列长度
# 获取队列中的数据
print(q.get())
print(q.get())
print(q.get())
q.task_done()
q.task_done()
q.task_done()
q.join()
>>>3
>>>1
>>>3
>>>4