Python數據結構與算法—優先級隊列Queue
前言
queue庫提供了一個適用于多線程編程的先進先出(FIFO)數據結構,可以用來在生產者與消費者線程之間安全地傳遞消息或其他數據。
它會為調用者處理鎖定,使多個線程可以安全而更容易地處理同一個Queue實例。Queue的大小可能受限,以限制內存使用或處理。
基本用法
Queue類實現了一個基本的先進先出容器。使用put()將元素增加到這個序列的一端,使用get()從另一端刪除。具體代碼如下所示:
- import queue
- q = queue.Queue()
- for i in range(1, 10):
- q.put(i)
- while not q.empty():
- print(q.get(), end=" ")
運行之后,效果如下:
這里我們依次添加1到10到隊列中,因為先進先出,所以出來的順序也與添加的順序相同。
LIFO隊列
既然有先進先出隊列queue,那么數據結構中肯定也有后進先出的隊列。后進先出的隊列為:LifoQueue,示例如下:
- import queue
- q = queue.LifoQueue()
- for i in range(1, 10):
- q.put(i)
- while not q.empty():
- print(q.get(), end=" ")
運行之后,效果如下:
優先隊列
在操作系統中,我們常常會根據優先級來處理任務,比如系統的優先級最高,我們肯定優先處理系統任務,然后才處理用戶的任務。同樣,queue庫給我們提供了PriorityQueue來處理優先級的隊列。
示例如下:
- import queue
- import threading
- class Job:
- def __init__(self, priority, desc):
- self.priority = priority
- self.desc = desc
- print("New Job:", desc)
- return
- def __eq__(self, other):
- try:
- return self.priority == other.priority
- except AttributeError:
- return NotImplemented
- def __lt__(self, other):
- try:
- return self.priority > other.priority
- except AttributeError:
- return NotImplemented
- def process_Job(q):
- while True:
- next_job = q.get()
- print(next_job.desc)
- q.task_done()
- q = queue.PriorityQueue()
- q.put(Job(5, "Five Job"))
- q.put(Job(15, "Fifteen Job"))
- q.put(Job(1, "One Job"))
- workers = [
- threading.Thread(target=process_Job, args=(q,)),
- threading.Thread(target=process_Job, args=(q,)),
- ]
- for work in workers:
- work.setDaemon(True)
- work.start()
- q.join()
運行之后,效果如下:
這里,我們默認數值越大優先級越高,可以看到15先執行,然后再是5,1任務。這個例子展現了有多個線程在處理任務時,要根據get()時隊列中元素的優先級來處理。