隊列中數據只有一份,取出就沒有了,區別於列表,列表數據取出只是複製了一份html
queue.Queue(maxsize=0)
示例:多線程
import queue q = queue.Queue() q.put(1) q.put(2) q.put(3) print(q.get()) print(q.get()) print(q.get())
輸出結果:
1
2
3線程
queue.LifoQueue
示例:code
import queue q = queue.LifoQueue() q.put(1) q.put(2) q.put(3) print(q.get()) print(q.get()) print(q.get())
輸出結果:
3
2
1htm
queue.PriorityQueue
同優先級的按照 ASCII 排序
示例:blog
import queue q = queue.PriorityQueue() q.put((2, '2')) q.put((1, '1')) q.put((3, '3')) q.put((1, 'a')) print(q.get()) print(q.get()) print(q.get()) print(q.get())
輸出結果:
(1, '1')
(1, 'a')
(2, '2')
(3, '3')排序
queue 模塊中有 Queue 類,LifoQueue、PriorityQueue 都繼承了 Queue繼承
maxsize 是實例化 Queue 類時的一個參數,默認爲 0
Queue(maxsize=0) 能夠控制隊列中數據的容量隊列
Queue.put(block=True, timeout=None)
block
用於設置是否阻塞, timeout
用於設置阻塞時等待時長
put_nowait() = put(block=False)開發
當隊列滿了以後,put 就會阻塞,一直等待隊列再也不滿時向裏面添加數據
當隊列滿了以後,若是設置 put 不阻塞,或者等待時長到了以後會報錯:queue.Full
Queue.get(block=True, timeout=None)
get_nowait() = get(block=False)
當隊列空了以後,get 就會阻塞,一直等待隊列中有數據後再獲取數據
當隊列空了以後,若是設置 get 不阻塞,或者等待時長到了以後會報錯:_queue.Empty
Queue.empty()
/Queue.full()
用於判斷隊列是否爲空、滿
儘可能使用 qsize
代替
Queue.qsize()
用於獲取隊列中大體的數據量
注意:在多線程的狀況下不可靠
由於在獲取 qsize 時,其餘線程可能又對隊列進行操做了
join
會在隊列存在未完成任務時阻塞,等待隊列無未完成任務,須要配合 task_done
使用
執行一次 put
會讓未完成任務 +1 ,可是執行 get
並不會讓未完成任務 -1 ,須要使用 task_done
讓未完成任務 -1 ,不然 join
就沒法判斷
隊列爲空時執行會報錯:ValueError: task_done() called too many times
示例:
import queue import threading import time def q_put(): for i in range(10): q.put('1') while True: q.put('2') time.sleep(1) def q_get(): while True: temp = q.get() q.task_done() print(temp) time.sleep(0.3) q = queue.Queue() t1 = threading.Thread(target=q_put) t2 = threading.Thread(target=q_get) t1.start() t2.start() q.join() print('queue is empty now')
主線程執行到 q.join
就開始阻塞,當 t2 線程將隊列中的數據所有取出以後,主線程才繼續執行。
若是將 task_done
註釋掉主線程就永遠阻塞在 q.join
,再也不繼續向下執行
在多線程開發當中,若是生產線程處理速度很快,而消費線程處理速度很慢,那麼生產線程就必須等待消費線程處理完,才能繼續生產數據。一樣的道理,若是消費線程的處理能力大於生產線程,那麼消費線程就必須等待生產線程。爲了解決這個問題因而引入了生產者和消費者模式
生產者消費者模式是經過一個容器來解決生產者和消費者的強耦合問題。生產者和消費者彼此之間不直接通信,而經過阻塞隊列來進行通信,因此生產者生產完數據以後不用等待消費者處理,直接扔給阻塞隊列,消費者不找生產者要數據,而是直接從阻塞隊列裏取,阻塞隊列就至關於一個緩衝區,平衡了生產者和消費者的處理能力。
示例:
import threading import time import queue def producer(): count = 1 while 1: q.put('No.%i' % count) print('Producer put No.%i' % count) time.sleep(1) count += 1 def customer(name): while 1: print('%s get %s' % (name, q.get())) time.sleep(1.5) q = queue.Queue(maxsize=5) p = threading.Thread(target=producer, ) c = threading.Thread(target=customer, args=('jack', )) p.start() c.start()
使用生成器也能夠實現簡單的生產者消費者模型
點擊查看 -> 生成器