[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
121會員
204內容數
本業是影像辨識軟體開發,閒暇時間進修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
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
想要開始Python語言的開發環境,有兩種常見方式,一種是下載安裝到本機端,另一種是直接在雲端執行。本文將介紹三個常見的開發工具及其安裝步驟。
隨著數據越來越成為商業和決策的關鍵因素,數據科學變得越來越重要。而Python,作為一個強大且多用途的編程語言,在數據科學領域中佔有重要地位。不管你是想在工作上提升技能,還是在個人生活中探索數據,Python都可以幫助你解鎖數據的力量。本文將介紹Python在數據科學中的應用,並提供一些入門指南,讓
Thumbnail
網路爬蟲(web crawler),也叫網路蜘蛛(spider) 是一個強大的自動化工具,可以自由瀏覽、擷取訪問網頁的各項資訊,例如:新聞文章、電商商品價格,當專案中需要添加外部數據或進行大量資料收集時,網路爬蟲就是一個非常實用的工具。
Thumbnail
探索Python學習筆記中列表的建立、存取和常用方法。從使用中括號定義列表到了解索引、新增、刪除、修改等操作,並介紹append、remove、count等常用方法。
Thumbnail
在本篇Python學習筆記中,我們探討了字典的建立與存取,以及常用方法,字典是一種強大的資料型態,透過key和value的對應關係存儲和取得資料,我們學會了建立字典、存取資料、新增/修改/刪除項目,以及取得key和value的方法,字典是Python中不可或缺的工具!
Thumbnail
我們可以利用工作表的append()方法,在工作表的列尾添加資料列。 利用迴圈的技巧,我們可以批次賦予區塊內所有儲存格相同的值。 我們也可以在指定的列(行)之前插入指定數量的空白列(行),從指定的列(行)開始向下(右)刪除指定數量的列(行)。
Thumbnail
我希望透過在好學校開設「Python 的 50+ 練習:資料科學學習手冊」,讓學生一步步完成這門課程所有的觀念講解、範例實作以及練習之後,扎實地將 Python 程式設計與資料科學應用納入自己的技能組,成為一位擅長寫程式處理資料的分析師,大幅提升工作掌握度與職涯發展性!
Thumbnail
Python 從創立之初的沒沒無名,至今被譽為「初學者最佳語言」,在 Python  社群背後默默貢獻的「鄉民」們居功厥偉!讓我們來看一下 Python 那些年的歷歷往事。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
想要開始Python語言的開發環境,有兩種常見方式,一種是下載安裝到本機端,另一種是直接在雲端執行。本文將介紹三個常見的開發工具及其安裝步驟。
隨著數據越來越成為商業和決策的關鍵因素,數據科學變得越來越重要。而Python,作為一個強大且多用途的編程語言,在數據科學領域中佔有重要地位。不管你是想在工作上提升技能,還是在個人生活中探索數據,Python都可以幫助你解鎖數據的力量。本文將介紹Python在數據科學中的應用,並提供一些入門指南,讓
Thumbnail
網路爬蟲(web crawler),也叫網路蜘蛛(spider) 是一個強大的自動化工具,可以自由瀏覽、擷取訪問網頁的各項資訊,例如:新聞文章、電商商品價格,當專案中需要添加外部數據或進行大量資料收集時,網路爬蟲就是一個非常實用的工具。
Thumbnail
探索Python學習筆記中列表的建立、存取和常用方法。從使用中括號定義列表到了解索引、新增、刪除、修改等操作,並介紹append、remove、count等常用方法。
Thumbnail
在本篇Python學習筆記中,我們探討了字典的建立與存取,以及常用方法,字典是一種強大的資料型態,透過key和value的對應關係存儲和取得資料,我們學會了建立字典、存取資料、新增/修改/刪除項目,以及取得key和value的方法,字典是Python中不可或缺的工具!
Thumbnail
我們可以利用工作表的append()方法,在工作表的列尾添加資料列。 利用迴圈的技巧,我們可以批次賦予區塊內所有儲存格相同的值。 我們也可以在指定的列(行)之前插入指定數量的空白列(行),從指定的列(行)開始向下(右)刪除指定數量的列(行)。
Thumbnail
我希望透過在好學校開設「Python 的 50+ 練習:資料科學學習手冊」,讓學生一步步完成這門課程所有的觀念講解、範例實作以及練習之後,扎實地將 Python 程式設計與資料科學應用納入自己的技能組,成為一位擅長寫程式處理資料的分析師,大幅提升工作掌握度與職涯發展性!
Thumbnail
Python 從創立之初的沒沒無名,至今被譽為「初學者最佳語言」,在 Python  社群背後默默貢獻的「鄉民」們居功厥偉!讓我們來看一下 Python 那些年的歷歷往事。