使用队列模块在Python中进行堆栈和排队
在Python中,实现堆栈和队列数据结构非常容易。Stack之所以称为LIFO,是因为Stack遵循“先进先出”的原则,而Queue之所以称为FIFO是因为Queue遵循“先进先出”的原则,而Python中的内置函数使代码更短,更简单。
队列模块实现了多生产者,多消费者队列,当必须在多个线程之间安全地交换信息时,它在线程编程中特别有用。该模块中的Queue类实现了所有必需的锁定语义,并且取决于Python中线程支持的可用性。
该模块实现了三种类型的队列,它们的区别仅在于检索条目的顺序不同。对于FIFO队列,添加的第一个任务是第一个检索到的;对于LIFO队列,最近添加的条目是第一个检索(像堆栈一样操作)。对于优先级队列,条目将保持排序(使用heapq模块),然后首先检索值最低的条目。
此队列模块定义以下类和异常。
Queue.Queue类(maxsize=0)
这是FIFO队列的构造函数。参数maxsize是一个整数,用于设置可以放入队列中的项目数的上限。一旦达到此大小,插入将被阻塞,直到消耗队列项目为止。如果maxsize小于或等于零,那么队列大小将是无限的。
Queue.LifoQueue类(maxsize=0)
这是LIFO队列的构造函数。参数maxsize是一个整数,用于设置可以放入队列中的项目数的上限。一旦达到此大小,插入将被阻塞,直到消耗队列项目为止。如果maxsize小于或等于零,那么队列大小将是无限的。
Queue.PriorityQueue(maxsize=0)类
这是优先级队列的构造函数。参数maxsize是一个整数,用于设置可以放入队列中的项目数的上限。一旦达到此大小,插入将被阻塞,直到消耗队列项目为止。如果maxsize小于或等于零,那么队列大小是无限的。
异常Queue.Empty
此行表示在get()
空对象的Queue对象上调用非阻塞(或get_nowait())时引发的异常。
异常Queue.Full
此行表示在put()
已满的Queue对象上调用非阻塞(或put_nowait())时引发的异常。
队列对象
Queue.qsize()
此函数返回队列的大概大小。
Queue.empty()
如果队列为空,则此函数返回True,否则返回False。如果empty()
返回True,则不保证后续的调用put()
不会阻塞。同样,如果empty()
返回False,则不能保证后续的调用get()
不会阻塞。
Queue.full()
如果队列已满,则返回True,否则返回False。如果full()
返回True,则不保证后续的调用get()
不会阻塞。同样,如果full()
返回False,则不能保证后续的调用put()
不会阻塞。
Queue.put(item[,block[,timeout]])
将项目放入队列。如果可选的args块为true,并且超时为None(默认值),则在必要时进行阻塞,直到有可用的插槽为止。如果超时为正数,则在最多超时秒内阻塞,并在该时间内没有可用插槽的情况下引发Full异常。否则(block为false),如果有空闲插槽立即可用,则将项目放入队列中,否则引发Full异常(在这种情况下将忽略超时)。
Queue.get([block[,timeout]])
从队列中删除并返回一个项目。如果可选的args块为true,并且超时为None(默认值),则必要时进行阻塞,直到有可用项为止。如果超时为正数,则它最多会阻塞超时秒,如果在该时间内没有可用的项目,则会引发Empty异常。否则(块为false),如果一项立即可用,则返回一个项目,否则引发Empty异常(在这种情况下将忽略超时)。
Queue.task_done()
表示先前入队的任务已完成。由队列使用者线程使用。对于每个get()
用于提取任务的任务,随后对task_done()的调用将告诉队列该任务的处理已完成。
如果ajoin()
当前正在阻塞,它将在所有项目都已处理完毕后恢复(这意味着已收到put()
队列中的每个项目都收到task_done()调用)。
如果调用的次数超过队列中放置的项目的次数,则引发ValueError。
Queue.join()
阻塞直到队列中的所有项目都已获得并处理。
每当将项目添加到队列时,未完成任务的数量就会增加。每当使用者线程调用task_done()表示已检索到该项目并且该项目的所有工作已完成时,该计数就会减少。当未完成的任务数降至零时,join()
取消阻止。
范例程式码
import queue #maximum capacity of queue is 20 Q = queue.Queue(maxsize=40) Q.put(50) Q.put(90) Q.put(10) Q.put(70) print(Q.get()) print(Q.get()) print(Q.get()) print(Q.get())
输出结果
50 90 10 70
下溢/上溢示例
import queue Q = queue.Queue(maxsize=30) print(Q.qsize()) Q.put(50) Q.put(90) Q.put(10) Q.put(70) print("Full: ", Q.full()) Q.put(90) Q.put(100) print("Full: ", Q.full()) print(Q.get()) print(Q.get()) print(Q.get()) print("Empty: ", Q.empty()) print(Q.get()) print(Q.get()) print(Q.get()) print("Empty: ", Q.empty()) print("Full: ", Q.full())
输出结果
0 Full: False Full: False 50 90 10 Empty: False 70 90 100 Empty: True Full: False
例3
import queue S = queue.LifoQueue(maxsize=10) # qsize() give the maxsize of # the Queue print(S.qsize()) S.put(50) S.put(90) S.put(10) S.put(70) S.put(90) S.put(10) print("Full: ", S.full()) print("Size: ", S.qsize()) # Data will be accessed in the # reverse order Reverse of that # of Queue print(S.get()) print(S.get()) print(S.get()) print(S.get()) print(S.get()) print("Empty: ", S.empty())
输出结果
0 Full: False Size: 6 10 90 70 10 90 Empty: False