35.python 線程隊列Queue-FIFO

之前的文章中講解很多關於線程間通信的知識,比如:線程互斥鎖lock線程事件event線程條件變量condition 等等,這些都是在開發中經常使用的內容,而今天繼續給大家講解一個更重要的知識點 — 線程隊列queue。

一.隊列分類:

1.線程隊列Queue — FIFO(先進先出隊列),即哪個數據先存入,取數據的時候先取哪個數據,同生活中的排隊買東西;

2.線程隊列LifoQueue — LIFO(先進後出隊列),即哪個數據最後存入的,取數據的時候先取;

3.線程隊列PriorityQueue — PriorityQueue(優先級隊列),即存入數據時候加入一個優先級,取數據的時候優先級最高的取出;

今天只對第一種普通線程隊列Queue(FIFO)講解,後面的兩種留到下一篇文章在做詳細講解!

 

 

二.先進先出隊列Queue簡介

線程隊列Queue,也稱FIFO,存在隊列中的數據先進先出,就好比拉肚子,吃什麼拉什麼~~呃呃,有點重口味,如下圖:

queue

 

舉個形象的例子:如果把123456這6個數字,依次放入隊列queue中,那麼我們重隊列中取數據的時候,取到的第一個數據必然是1,第二個數據必然是2,依次類推,這就是所謂的吃什麼拉什麼 — FIFO(先進先出)

蹲坑

 

三.先進先出隊列Queue常用函數

Queue.qsize()    返回隊列大小

Queue.empty()  判斷隊列是否爲空

Queue.full()        判斷隊列是否滿了

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之後,主線程就不會因爲隊列空了而擅自結束,而是等待最後那個線程處理完成了。

 

 

四.先進先出隊列Queue使用:


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

 

 

猜你喜歡:

1.pycharm配置開發模板

2.python字典推導式

3.python列表推導式

4.python匿名函數lambda

 

轉載請註明猿說Python » python線程隊列Queue-FIFO

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章