專欄地址:每週一個 Python 模組
Queue 是 Python 標準庫中的執行緒安全的佇列(FIFO)實現,提供了一個適用於多執行緒程式設計的先進先出的資料結構,即佇列,用來在生產者和消費者執行緒之間的資訊傳遞。
有一點需要注意,Python2 中模組名是 Queue,而 Python3 是 queue。
基本 FIFO 佇列
class Queue.Queue(maxsize=0)
FIFO 即 First in First Out,先進先出。Queue 提供了一個基本的 FIFO 容器,使用方法很簡單,maxsize 是個整數,指明瞭佇列中能存放的資料個數的上限。一旦達到上限,插入會導致阻塞,直到佇列中的資料被消費掉。如果maxsize 小於或者等於 0,佇列大小沒有限制。
舉個栗子:
import Queue
q = Queue.Queue()
for i in range(5):
q.put(i)
while not q.empty():
print q.get()
# output
# 0
# 1
# 2
# 3
# 4
複製程式碼
LIFO 佇列
class Queue.LifoQueue(maxsize=0)
LIFO 即 Last in First Out,後進先出。與棧的類似,使用也很簡單,maxsize 用法同上。
再舉個栗子:
import Queue
q = Queue.LifoQueue()
for i in range(5):
q.put(i)
while not q.empty():
print q.get()
# output
# 4
# 3
# 2
# 1
# 0
複製程式碼
可以看到僅僅是將Queue.Quenu
類替換為Queue.LifoQueue
類。
優先順序佇列
class Queue.PriorityQueue(maxsize=0)
構造一個優先佇列。maxsize 用法同上。
import Queue
import threading
class Job(object):
def __init__(self, priority, description):
self.priority = priority
self.description = description
print 'Job:',description
return
def __cmp__(self, other):
return cmp(self.priority, other.priority)
q = Queue.PriorityQueue()
q.put(Job(3, 'level 3 job'))
q.put(Job(10, 'level 10 job'))
q.put(Job(1, 'level 1 job'))
def process_job(q):
while True:
next_job = q.get()
print 'for:', next_job.description
q.task_done()
workers = [threading.Thread(target=process_job, args=(q,)),
threading.Thread(target=process_job, args=(q,))
]
for w in workers:
w.setDaemon(True)
w.start()
q.join()
# output
# Job: level 3 job
# Job: level 10 job
# Job: level 1 job
# for: level 1 job
# for: level 3 job
# for: job: level 10 job
複製程式碼
一些常用方法
task_done()
意味著之前入隊的一個任務已經完成。由佇列的消費者執行緒呼叫。每一個 get()
呼叫得到一個任務,接下來的 task_done()
呼叫告訴佇列該任務已經處理完畢。
如果當前一個join()
正在阻塞,它將在佇列中的所有任務都處理完時恢復執行(即每一個由put()
呼叫入隊的任務都有一個對應的task_done()
呼叫)。
join()
阻塞呼叫執行緒,直到佇列中的所有任務被處理掉。
只要有資料被加入佇列,未完成的任務數就會增加。當消費者執行緒呼叫task_done()
(意味著有消費者取得任務並完成任務),未完成的任務數就會減少。當未完成的任務數降到 0,join()
解除阻塞。
put(item[, block[, timeout]])
將item
放入佇列中。
- 如果可選的引數
block
為True
且timeout
為空物件(預設的情況,阻塞呼叫,無超時)。 - 如果
timeout
是個正整數,阻塞呼叫程式最多timeout
秒,如果一直無空空間可用,丟擲Full
異常(帶超時的阻塞呼叫)。 - 如果
block
為False
,如果有空閒空間可用將資料放入佇列,否則立即丟擲Full
異常。
其非阻塞版本為put_nowait
等同於put(item, False)
。
get([block[, timeout]])
從佇列中移除並返回一個資料。block
跟timeout
引數同put
方法。其非阻塞方法為get_nowait()
相當與get(False)
。
empty()
如果佇列為空,返回True
,反之返回False
。
相關文件: