以前的文章中講解不少關於線程間通訊的知識,好比:線程互斥鎖lock,線程事件event,線程條件變量condition 等等,這些都是在開發中常常使用的內容,而今天繼續給你們講解一個更重要的知識點 — 線程隊列queue。python
1.線程隊列Queue — FIFO(先進先出隊列),即哪一個數據先存入,取數據的時候先取哪一個數據,同生活中的排隊買東西;git
2.線程隊列LifoQueue — LIFO(先進後出隊列),即哪一個數據最後存入的,取數據的時候先取;github
3.線程隊列PriorityQueue — PriorityQueue(優先級隊列),即存入數據時候加入一個優先級,取數據的時候優先級最高的取出;微信
今天只對第一種普通線程隊列Queue(FIFO)講解,後面的兩種留到下一篇文章在作詳細講解!ide
線程隊列Queue,也稱FIFO,存在隊列中的數據先進先出,就比如拉肚子,吃什麼拉什麼~~呃呃,有點重口味,以下圖:函數
舉個形象的例子:若是把123456這6個數字,依次放入隊列queue中,那麼咱們重隊列中取數據的時候,取到的第一個數據必然是1,第二個數據必然是2,依次類推,這就是所謂的吃什麼拉什麼 — FIFO(先進先出)spa
Queue.qsize() 返回隊列大小線程
Queue.empty() 判斷隊列是否爲空code
Queue.full() 判斷隊列是否滿了orm
Queue.get([block[,timeout]]) 從隊列頭刪除並返回一個item,block默認爲True,表示當隊列爲空卻去get的時候會阻塞線程,等待直到有有item出現爲止來get出這個item。若是是False的話代表當隊列爲空你卻去get的時候,會引起異常。在block爲True的狀況下能夠再設置timeout參數。表示當隊列爲空,get阻塞timeout指定的秒數以後尚未get到的話就引起Full異常。
Queue.task_done() 從場景上來講,處理完一個get出來的item以後,調用task_done將向隊列發出一個信號,表示本任務已經完成(與Queue.get配對使用)。
Queue.put(…[,block[,timeout]]) 向隊尾插入一個item,一樣若block=True的話隊列滿時就阻塞等待有空位出來再put,block=False時引起異常。同get的timeout,put的timeout是在block爲True的時候進行超時設置的參數。
Queue.join() 監視全部item並阻塞主線程,直到全部item都調用了task_done以後主線程才繼續向下執行。這麼作的好處在於,假如一個線程開始處理最後一個任務,它從任務隊列中拿走最後一個任務,此時任務隊列就空了但最後那個線程還沒處理完。當調用了join以後,主線程就不會由於隊列空了而擅自結束,而是等待最後那個線程處理完成了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# !usr/bin/env python # -*- coding:utf-8 _*- """ @Author:何以解憂 @Blog(我的博客地址): shuopython.com @WeChat Official Account(微信公衆號):猿說python @Github:www.github.com
@File:python_queue.py @Time:2019/11/29 15:25
@Motto:不積跬步無以致千里,不積小流無以成江海,程序人生的精彩須要堅持不懈地積累! """
import threading import queue
q = queue.Queue(5) # 長度,隊列中最多存放5個數據
def put(): for i in range(20): q.put(i) print("數字%d存入隊列成功" % i) q.join() # 阻塞進程,直到全部任務完成,取多少次數據task_done多少次才行,不然最後的ok沒法打印 print('ok')
def get(): for i in range(20): value = q.get() print("數字%d重隊列中取出" % value) q.task_done() # 必須每取走一個數據,發一個信號給join # q.task_done() #放在這沒用,由於join其實是一個計數器,put了多少個數據, # 計數器就是多少,每task_done一次,計數器減1,直到爲0才繼續執行
t1 = threading.Thread(target=put, args=()) t1.start() t2 = threading.Thread(target=get, args=()) t2.start() |
輸出結果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
數字0存入隊列成功 數字1存入隊列成功 數字2存入隊列成功 數字3存入隊列成功 數字4存入隊列成功 數字0重隊列中取出 數字1重隊列中取出 數字2重隊列中取出 數字3重隊列中取出 數字4重隊列中取出 數字5存入隊列成功 數字6存入隊列成功 數字7存入隊列成功 數字8存入隊列成功 數字9存入隊列成功 數字5重隊列中取出 數字6重隊列中取出 數字7重隊列中取出 數字8重隊列中取出 數字9重隊列中取出 數字10存入隊列成功 數字11存入隊列成功 數字12存入隊列成功 數字13存入隊列成功 數字14存入隊列成功 數字10重隊列中取出 數字11重隊列中取出 數字12重隊列中取出 數字15存入隊列成功 數字16存入隊列成功 數字17存入隊列成功 數字13重隊列中取出 數字14重隊列中取出 數字15重隊列中取出 數字16重隊列中取出 數字18存入隊列成功 數字19存入隊列成功 數字17重隊列中取出 數字18重隊列中取出 數字19重隊列中取出 ok |
轉載請註明:猿說Python » python線程隊列Queue-FIFO