日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Python 标准库之 Queue

發布時間:2023/11/28 生活经验 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python 标准库之 Queue 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. Queue 概念

隊列 Queue 多應用在多線程應用中,多線程訪問共享變量。對于多線程而言,訪問共享變量時,隊列 Queue 是線程安全的。

Python Queue 模塊有三種隊列及構造函數:

  1. Python Queue模塊的FIFO隊列先進先出。
   class Queue.Queue(maxsize)
  1. LIFO類似于堆,即先進后出。
   class Queue.LifoQueue(maxsize)
  1. 還有一種是優先級隊列級別越低越先出來。即隊列中的元素是一個元祖類型,(優先級級別,數據)。
   class Queue.PriorityQueue(maxsize)

2. Queue 常用的方法

q = Queue.Queue()
函數說明
q.qsize()返回隊列的大小
q.empty()如果隊列為空,返回True,反之False
q.full()如果隊列滿了,返回True,反之False
q.get([block[, timeout]])獲取隊列,timeout等待時間
q.get_nowait()相當q.get(False),無阻塞的向隊列中get任務,當隊列為空時,不等待,而是直接拋出empty異常,重點是理解block = False:
q.put(item)非阻塞寫入隊列,timeout等待時間
q.put_nowait(item)相當q.put(item, False),無阻塞的向隊列中添加任務,當隊列為滿時,不等待,而是直接拋出full異常,重點是理解block = False
q.task_done()在完成一項工作之后,q.task_done() 函數向任務已經完成的隊列發送一個信號
q.join()阻塞等待隊列中任務全部處理完畢,需要配合queue.task_done使用

重點方法說明:

2.1 get() 方法

from Queue import Queue
Queue.get(self, block=True, timeout=None)

調用隊列對象的 get() 方法從隊頭刪除并返回一個項目。可選參數為 block,默認為 True。

  • 如果隊列為空且 block 為 True,get() 就使調用線程暫停,直至有項目可用。
  • 如果隊列為空且 block 為 False,隊列將引發 Empty 異常。

2.2 put() 方法

from Queue import Queue
Queue.put(self, item, block=True, timeout=None)

調用隊列對象的 put() 方法在隊尾插入一個項目。put() 有三個參數,第一個 item 為必需的,為插入項目的值;第二個 block 為可選參數,默認為 True。

  • 如果隊列當前為空且 block 為 True,put() 方法就使調用線程暫停,直到空出一個數據單元。
  • 如果block為 False,put 方法將引發 Full 異常

從上面說明可以看到,當一個隊列為空的時候如果再用 get 取則會堵塞,所以取隊列的時候一般是用到 get_nowait() 方法,這種方法在向一個空隊列取值的時候會拋一個 Empty 異常,所以更常用的方法是先判斷一個隊列是否為空,如果不為空則取值。

from Queue import Queuemy_queue = Queue(maxsize=10)
# 定義隊列時有一個默認的參數maxsize, 如果不指定隊列的長度,即maxsize=0,那么隊列的長度為無限長,如果定義了大于0的值,那么隊列的長度就是maxsize。
a = [1, 2, 3]
my_queue.put(a)
print my_queue.get()
print my_queue.get()    # 再次調用時進程一直未結束,處于等待隊列中有值的狀態

3. 注意事項

3.1 阻塞模式

import Queueq = Queue.Queue(10)......
for i in range(10):q.put('A')time.sleep(0.5)

這是一段極其簡單的代碼(另有兩個線程也在操作隊列 q),我期望每隔 0.5 秒寫一個’A’到隊列中,但總是不能如愿:間隔時間有時會遠遠超過 0.5 秒。

原來,Queue.put()默認有 block = True 和 timeout 兩個參數。當 block = True 時,寫入是阻塞式的,阻塞時間由 timeout 確定。

當隊列 q 被(其他線程)寫滿后,這段代碼就會阻塞,直至其他線程取走數據。Queue.put()方法加上 block=False 的參數,即可解決這個隱蔽的問題。但要注意,非阻塞方式寫隊列,當隊列滿時會拋出 exception Queue.Full 的異常。

?

3.1 無法捕獲 exception Queue.Empty 的異常

while True:......try:data = q.get()except Queue.Empty:break

我的本意是用隊列為空時,退出循環,但實際運行起來,卻陷入了死循環。這個問題和上面有點類似:Queue.get()默認的也是阻塞方式讀取數據,隊列為空時,不會拋出 except Queue.Empty ,而是進入阻塞直至超時。 加上block=False 的參數,問題迎刃而解。

參考:

https://blog.csdn.net/zy205817/article/details/51388479

https://blog.csdn.net/yatere/article/details/6668006

總結

以上是生活随笔為你收集整理的Python 标准库之 Queue的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。