[Python][微進階]Queue佇列中的資料被多個執行緒並行處理

更新於 發佈於 閱讀時間約 8 分鐘

在Python中,queue是一個非常有用的模块。

它提供了多種佇列(queue)實現,用於在多線程環境中安全地交換信息或者數據

佇列(queue)是一種先進先出(FIFO)的數據結構,允許在佇列的一端插入元素,另一端取出元素。(FIFO First In, First Out 的縮寫)

FIFO

FIFO


以下是Python中queue模塊的基本用法及相關說明:

創建佇列

使用Queue類來創建一個佇列對象。可以指定佇列的最大長度,如果不指定,則默認為無限長度的佇列。

import queue

q = queue.Queue(maxsize=10) # 創建一個最大長度為10的佇列



放入元素

使用put()方法向佇列中放入一個元素。

q.put(item)



取出元素

使用get()方法從佇列中取出一個元素,如果佇列為空,則會阻塞直到有元素可用。

item = q.get()


判斷佇列是否為空

使用empty()方法可以判斷佇列是否為空。

if q.empty():
print("Queue is empty")


判斷佇列是否已滿

使用full()方法可以判斷佇列是否已滿,僅適用於有限長度的佇列。


設置阻塞與非阻塞操作

默認情況下,佇列的put()get()操作是阻塞的,如果你想要非阻塞的行為,可以使用put_nowait()get_nowait()方法。

q.put_nowait(item)
item = q.get_nowait()


佇列的阻塞操作

佇列的阻塞操作意味着當佇列為空時,get()操作將會等待直到有元素可用;當佇列已滿時,put()操作將會等待直到有空間可用。這樣可以很容易地實現生產者-消費者模式。

程式範例說明解釋阻塞與非阻塞操作



非阻塞操作

import queue

my_queue = queue.Queue(maxsize=2)

# 使用 put_nowait() 方法放入元素,即使佇列已滿也不會等待
try:
my_queue.put_nowait("Item 1")
my_queue.put_nowait("Item 2")
my_queue.put_nowait("Item 3") # 這裡會引發異常,因為佇列已滿
except queue.Full:
print("Queue is full, unable to put item.")

# 使用 get_nowait() 方法取出元素,即使佇列為空也不會等待
try:
item1 = my_queue.get_nowait()
item2 = my_queue.get_nowait()
item3 = my_queue.get_nowait() # 這裡會引發異常,因為佇列為空
except queue.Empty:
print("Queue is empty, unable to get item.")



輸出

Queue is full, unable to put item.
Queue is empty, unable to get item.


阻塞操作

import queue
import time
my_queue = queue.Queue(maxsize=2)

# 使用 put_nowait() 方法放入元素,即使佇列已滿也不會等待
# 時間計數來確認,等待多久才,等待多久才引發異常
start_time = time.time()
try:
my_queue.put("Item 1", timeout=1) #若未設定timout將會無限期等待
my_queue.put("Item 2", timeout=1)
my_queue.put("Item 3", timeout=1) # 這裡會引發異常,因為佇列已滿,等待一秒若無資料則會引發異常
except queue.Full:
print("Queue is full, unable to put item.")

end_time = time.time()
print(f'put處理時間 :{(end_time - start_time):6f}秒')
# 使用 get_nowait() 方法取出元素,即使佇列為空也不會等待

start_time = time.time()
try:
item1 = my_queue.get(timeout=1)
item2 = my_queue.get(timeout=1)
item3 = my_queue.get(timeout=1) # 這裡會引發異常,因為佇列為空
except queue.Empty:
print("Queue is empty, unable to get item.")

end_time = time.time()
print(f'put處理時間 :{(end_time - start_time):6f}秒')



輸出

Queue is full, unable to put item.
put處理時間 :1.001525
Queue is empty, unable to get item.
put處理時間 :1.000238

程式範例

主要流程如下:

1.創建一個佇列 my_queue,並將10個資料放入佇列中

放入佇列示意圖

放入佇列示意圖

2.創建兩個Plan執行緒 Plan_APlan_B,並將佇列物件和執行緒編號傳遞給它們。

3.啟動兩個執行緒,使其同時開始取出佇列中的資料。

取出Queue資料

取出Queue資料

4.使用join()方法等待兩個執行緒完成處理。

5.印出 "Done." 表示處理完成

import time
import threading
import queue

# Plan 類別
class Plan(threading.Thread):
def __init__(self, queue, num):
threading.Thread.__init__(self)
self.queue = queue
self.num = num

def run(self):
while self.queue.qsize() > 0:
# 取得新的資料
msg = self.queue.get()
# 印出資料
print(f'Plan_{self.num} : {msg}')
time.sleep(1)

# 建立佇列
my_queue = queue.Queue()

for i in range(10):
my_queue.put(f'Data : {i}')
print(f'查看佇列資料長度: {my_queue.qsize()}')

# 建立兩個 Plan
Plan_A = Plan(my_queue, 'A')
Plan_B = Plan(my_queue, 'B')

# 讓 Worker 開始取出資料
Plan_A.start()
Plan_B.start()

# 等待所有 Worker 結束
Plan_A.join()
Plan_B.join()

print("Done.")

輸出

查看佇列資料長度: 10
Plan_A : Data : 0
Plan_B : Data : 1
Plan_A : Data : 2
Plan_B : Data : 3
Plan_A : Data : 4
Plan_B : Data : 5
Plan_A : Data : 6
Plan_B : Data : 7
Plan_A : Data : 8
Plan_B : Data : 9
Done.

參考文獻

[Python][微進階]threading 多執行緒平行處理

https://docs.python.org/zh-tw/3/library/queue.html#module-queue

avatar-img
131會員
218內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
螃蟹_crab的沙龍 的其他內容
當你需要在 Python 中執行多個任務,但又不希望它們相互阻塞時,可以使用 threading 模組。 threading 模組允許你在單個程序中創建多個執行緒,這些執行緒可以同時運行,從而實現並行執行多個任務的效果。
在這篇文章中,我們講述瞭如何使用numpy.where方法查找Numpy數組中值的索引。除了介紹了numpy.where的基本用法外,還舉了一些應用實例進行了詳細說明。文章最後提供了其他應用領域以及相關參考文獻。
f字符串(f-string)在Python 3.6版本引入了新特性,可以更方便地格式化字符串。本文介紹了f-string的基本使用方法,以及表達式、運算符、格式化控制、字典和列表的應用,以及調用方法和函數等。f-string提供了一種更靈活的方式,使你能夠控制字符串的外觀,以滿足不同情況下的需求。
NumPy 提供了一種 N 維數組類型 ndarray(N-dimensional array) ,它描述了相同類型的「數據類型」的集合。 多維數組: ndarray 是一個 N 維數組,其中 N 可以是任意整數。一維數組是向量,二維數組是矩陣
NumPy在圖像處理、機器學習、數學和統計學等領域中被廣泛應用。 以下是一些常見的應用場景: 數據處理和分析: NumPy提供了高效的多維數組(nd array)和相應的操作函數,使得對大型數據集進行快速、有效的操作變得容易。
在程式開發中,協作合作專案時,利用type hint,可以快速知道函式輸入及輸出的資料型別,在後續的維護時也會更加方便及可讀。 Type hints 是Python 3.5 版本引入的功能,它允許在函數宣告中指定參數和傳回值的類型。Type hints 是一種可選的註解形式,不會影響程式碼的運行,
當你需要在 Python 中執行多個任務,但又不希望它們相互阻塞時,可以使用 threading 模組。 threading 模組允許你在單個程序中創建多個執行緒,這些執行緒可以同時運行,從而實現並行執行多個任務的效果。
在這篇文章中,我們講述瞭如何使用numpy.where方法查找Numpy數組中值的索引。除了介紹了numpy.where的基本用法外,還舉了一些應用實例進行了詳細說明。文章最後提供了其他應用領域以及相關參考文獻。
f字符串(f-string)在Python 3.6版本引入了新特性,可以更方便地格式化字符串。本文介紹了f-string的基本使用方法,以及表達式、運算符、格式化控制、字典和列表的應用,以及調用方法和函數等。f-string提供了一種更靈活的方式,使你能夠控制字符串的外觀,以滿足不同情況下的需求。
NumPy 提供了一種 N 維數組類型 ndarray(N-dimensional array) ,它描述了相同類型的「數據類型」的集合。 多維數組: ndarray 是一個 N 維數組,其中 N 可以是任意整數。一維數組是向量,二維數組是矩陣
NumPy在圖像處理、機器學習、數學和統計學等領域中被廣泛應用。 以下是一些常見的應用場景: 數據處理和分析: NumPy提供了高效的多維數組(nd array)和相應的操作函數,使得對大型數據集進行快速、有效的操作變得容易。
在程式開發中,協作合作專案時,利用type hint,可以快速知道函式輸入及輸出的資料型別,在後續的維護時也會更加方便及可讀。 Type hints 是Python 3.5 版本引入的功能,它允許在函數宣告中指定參數和傳回值的類型。Type hints 是一種可選的註解形式,不會影響程式碼的運行,
你可能也想看
Google News 追蹤
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
更快、更短、更即時是串流傳輸必要的元素, 而我們常常在使用Python請求API時都是等待式回應, 也就是一個請求過去之後, 待對方處理完畢後再行回應, 但假設需要下載的檔案、內容非常大時, 是不是使用者只能傻傻的等待整個傳輸結束後才能顯示? 這樣的使用者體驗也實在太糟糕了, 對於使用者來說除了完全
Thumbnail
Python的模組和庫是可重用的程式碼塊,可透過import語句引入。特定部分可以透過from和import引入,並可使用as指定別名。第三方模組可透過pip工具安裝並在程式碼中使用。此外,也可以創建自定義模組並在其他Python文件中引用。
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
Thumbnail
今天來介紹python的函式 函式在python中是非常重要的一環,因為到了後期,程式會越來越複雜。 而函式可以想成是容易管理的小程式,當我們需要使用時,只需呼叫即可。
Thumbnail
古有四大名著,現今Python四大容器🤣 哪四個?list串列,tuple元組,dict字典,set集合。 那這四個怎麼分? 一起來看看吧! (以下有手寫與上機實際測試請付費觀看) 以上我精心整理主要會使用到的功能 當然python功能太多了,肯定不只。 實際操作: 大概就這樣?(
Thumbnail
當我們在撰寫一套系統的時候, 總是會提供一個介面讓使用者來觸發功能模組並回傳使用者所需的請求, 而傳統的安裝包模式總是太侷限, 需要個別主機獨立安裝, 相當繁瑣, 但隨著時代的演進與互聯網的崛起, 大部分的工作都可以藉由網頁端、裝置端來觸發, 而伺服端則是負責接收指令、運算與回傳結果, 雲端
Thumbnail
關於多執行緒/多行程的使用方式 在Python 3.2版本之後加入了「concurrent.futures」啟動平行任務, 它可以更好的讓我們管理多執行緒/多行程的應用場景,讓我們在面對這種併發問題時可以不必害怕, 用一個非常簡單的方式就能夠處裡, 底下我們將為您展示一段程式碼: imp
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
更快、更短、更即時是串流傳輸必要的元素, 而我們常常在使用Python請求API時都是等待式回應, 也就是一個請求過去之後, 待對方處理完畢後再行回應, 但假設需要下載的檔案、內容非常大時, 是不是使用者只能傻傻的等待整個傳輸結束後才能顯示? 這樣的使用者體驗也實在太糟糕了, 對於使用者來說除了完全
Thumbnail
Python的模組和庫是可重用的程式碼塊,可透過import語句引入。特定部分可以透過from和import引入,並可使用as指定別名。第三方模組可透過pip工具安裝並在程式碼中使用。此外,也可以創建自定義模組並在其他Python文件中引用。
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
Thumbnail
今天來介紹python的函式 函式在python中是非常重要的一環,因為到了後期,程式會越來越複雜。 而函式可以想成是容易管理的小程式,當我們需要使用時,只需呼叫即可。
Thumbnail
古有四大名著,現今Python四大容器🤣 哪四個?list串列,tuple元組,dict字典,set集合。 那這四個怎麼分? 一起來看看吧! (以下有手寫與上機實際測試請付費觀看) 以上我精心整理主要會使用到的功能 當然python功能太多了,肯定不只。 實際操作: 大概就這樣?(
Thumbnail
當我們在撰寫一套系統的時候, 總是會提供一個介面讓使用者來觸發功能模組並回傳使用者所需的請求, 而傳統的安裝包模式總是太侷限, 需要個別主機獨立安裝, 相當繁瑣, 但隨著時代的演進與互聯網的崛起, 大部分的工作都可以藉由網頁端、裝置端來觸發, 而伺服端則是負責接收指令、運算與回傳結果, 雲端
Thumbnail
關於多執行緒/多行程的使用方式 在Python 3.2版本之後加入了「concurrent.futures」啟動平行任務, 它可以更好的讓我們管理多執行緒/多行程的應用場景,讓我們在面對這種併發問題時可以不必害怕, 用一個非常簡單的方式就能夠處裡, 底下我們將為您展示一段程式碼: imp