Python中的隊列模塊實現了多生產者和多消費者模型,在多線程編程需要時非常實用。而且這個模塊中的隊列類實現了鎖原語,所以不需要考慮多線程的安全問題。
模塊內置了三種類型的隊列,即類隊列。隊列(maxsize=0),類隊列。LifoQueue(maxsize=0)和classqueue。優先級隊列(maxsize = 0)。三者的區別只是拿出來的順序不壹致。
Queue是壹個FIFO隊列,任務按照相加的順序取出。
LifoQueue是壹個LIFO隊列,類似於堆棧,添加的任務先取出。
PriorityQueue是優先級隊列。隊列中的任務按優先級排序,優先級高的先取出。
可以看到,上面提到的內置隊列有三種不同的類型,其中maxsize是壹個整數,用來設置可以放入隊列的任務數的上限。當達到這個大小時,插入操作將阻止隊列中的任務被使用。如果maxsize小於或等於零,則隊列大小是無限的。
要將任務添加到隊列中,只需直接調用put()函數。
put()函數的完整函數簽名如下:queue.put (item,block = true,timeout = none)。正如您所看到的,這個函數有兩個可選參數。
默認情況下,當隊列已滿時,該函數將阻塞,直到隊列中有空間添加任務。如果超時是正數,它將阻止超時最多兩秒鐘,如果在此時間內沒有空缺位置,將拋出壹個完整的異常。
當block為false時,超時參數將無效。同時,如果隊列中沒有多余的位置來添加任務,則會拋出壹個滿異常,否則會將任務直接放入隊列中,不進行阻塞返回。
另外還可以通過Queue.put_nowait(item)添加任務,相當於Queue.put(item,False),這裏就不贅述了。類似地,當隊列滿了,這個操作將拋出壹個滿異常。
要從隊列中獲取任務,只需直接調用get()函數。
和put()函數壹樣,get()函數也有兩個可選參數,完整的簽名如下:queue.get (block = true,timeout = none)。
默認情況下,當隊列為空時調用此函數將會阻塞,直到隊列中有任務可用。如果timeout是壹個正數,它將阻塞超時最多秒,如果在此時間內沒有可用的任務,將拋出壹個空異常。
當block為false時,超時參數將無效。同時,如果隊列中沒有任務可用,會立即拋出壹個空異常,否則會直接獲取壹個任務,不阻塞返回。
另外,還可以通過Queue.get_nowait()獲取任務,相當於Queue.get(False),這裏不再贅述。同樣,當隊列為空時,該操作將拋出壹個空異常。
函數的作用是:返回隊列的大小。註意這個大小並不準確,qsize() > 0並不能保證後續的get()不會被阻塞。類似地,qsize()
如果隊列為空,則返回True,否則返回False。如果empty()返回True,則不能保證後續調用的put()不會被阻塞。同樣,如果empty()返回False,也不能保證後續調用的get()不會被阻塞。
如果隊列已滿,則返回True,否則返回False。如果full()返回True,則不能保證後續調用的get()不會被阻塞。同樣,如果full()返回False,也不能保證後續調用的put()不會被阻塞。
排隊。Queue()是壹個FIFO隊列,出隊順序與入隊順序相同。
排隊。LifoQueue()是LIFO queue,出隊順序與入隊順序完全相反,類似於堆棧。
優先級隊列中任務的順序與放入時的順序無關,而是按照任務的大小排序,先取出最小值。任務大小的規則是什麽?
註意,因為列表的比較規則是按下標順序比較的,所以在比較大小之前,隊列中所有列表對應下標位置的元素類型應該是壹致的。
比如[2,1]和["1 "," b"]因為第壹個位置的元素類型不壹樣,所以不能放入優先級隊列。
但是對於[2,1]和[1," b"],即使第二個元素的類型不壹致,也可以放入優先級隊列,因為只能比較第壹個位置元素的大小,不需要比較第二個位置元素的大小。
但是對於[2,1]和1 [2," b"],同樣不允許放入優先級隊列,因為需要比較第二個位置的元素才能比較結果。但是,第二個位置的元素類型不壹致,無法比較大小。
綜上所述,也就是說,在比較結果之前,對應下標位置的元素類型需要保持壹致。
我們自定義壹個動物類型,希望能按年齡排序。年齡越小,優先級越高。
本章介紹隊列及其常見操作。因為隊列默認實現了鎖原語,所以在多線程編程中不需要考慮多線程的安全性,對程序員來說是相當友好的。