【💊 Python的解憂錦囊】如何在multithread/multiprocess傳遞固定參數?

閱讀時間約 11 分鐘
raw-image


撰寫Python的朋友都知道multithread/multiprocess能為我們帶來效能的改進,減少硬體資源的閒置,但在撰寫的過程中常常會發現到我們所設計的工作池模式會需要將「待辦清單」的工作項目當成參數傳遞進去執行, 除了「待辦清單」之外, 其餘的參數基本上都是固定的, 基於這樣的需求之下, 我們要怎麼完成呢? 讓我們耐心的看完這個篇章。

我們通常會這樣做…

假設我們設計了一個工作但尚未實作工作詳細內容, 僅印出工作資訊如下 :

def job(name: str, action: str, item: str):
"""工作內容

Args :
name (str): 什麼樣的工作
action (str): 工作的行為(加工、蓋房、...)
item: 工作的項目
Retruns:
None
"""
result = f'{name} 正在 {action} {item}'
return result

接著我們在主程序設計好我們要執行「什麼樣的工作」、「工作的行為」, 接著我們會有許多的「待辦事項」需要執行, 接著招聘好工人(num_workers)之後就可以根據作業區擴展廠區(pool),每個作業區獨立運作這些待辦清單, 那我們可能會這樣撰寫程式:


import concurrent.futures

if __name__ == "__main__":
# 設計今天的主題
name = '食品加工廠'
action = '製作'

# 待辦事項
todo_list = ['熱狗', '炸雞', '薯條', '肉乾']

num_workers = 3

# 創建一個多進程池,根據上述的工人數量擴展工作池
with concurrent.futures.ProcessPoolExecutor(max_workers=num_workers) as executor:

# 我們將大量的待辦事項轉換成每個worker需要執行的
params = [(name, action, item) for item in todo_list]
results = executor.map(job, params)

# 印出執行結果
for result in results:
print(result)
raw-image


但上述的作法真的好嗎?

我們的params不會隨著「待辦清單」越多(上千萬個事項), 導致記憶體爆掉嗎? 不妨來看看我們更改後的範例, 假設有1000萬的「待辦清單」時會發生什麼狀況? 我們也順便埋入執行的估測時間來實際看看結果。

import multiprocessing
import time
import random
import sys

def job(name: str, action: str, item: str):
"""工作內容

Args :
name (str): 工作名稱
action (str): 動作
item: 工作的項目
Retruns:
None
"""
secs = random.random()
result = f'{name} 正在 {action} {item} 花費了 {secs} 秒'
time.sleep(secs)
return result

if __name__ == "__main__":
# 固定的參數
name = '食品加工廠'
action = '製作'

# 主程序提供的待辦事項清單
# todo_list = ['熱狗', '炸雞', '薯條', '肉乾']
todo_list = [f"工作{i}" for i in range(1, 10000000)]

num_workers = 3

# 創建一個多進程池,這裡使用3個進程
with multiprocessing.Pool(processes=num_workers) as pool:
start_time = time.time()
params = [(name, action, item) for item in todo_list]
end_time = time.time()

use_bytes = sys.getsizeof(params)
use_mb = use_bytes / 1048576
print(f'渲染參數花費的時間: {end_time - start_time} 秒, 耗用的記憶體: {use_mb} MB')

results = pool.starmap(job, params)
for result in results:
print(result)

我們會發現以下光是簡單的參數就花費如此之多的記憶體耗用量, 那面對大數據時怎麼辦?

raw-image

因此我們可以這樣做…

我們在「【Python 軍火庫🧨 - functools】使用partial來設計函數樣板」有介紹到「functools.partial」這個工具庫, 我們可以利用partial的技巧製造出固定參數的新函式, 以不變應萬變,套用到multiprocess之前就不需要一堆複製的資源耗費…。

那在進入主題之前, 我們先來複習一下關於functools.partial函式, 他可以幫我們製作出固定參數的樣版。

raw-image


但聰明的大家有沒有觀察到一個狀況, 那就是動態的參數通常在前面(a, b), 而固定的參數放在後段(c), 因此底下我們的job的參數設計勢必要改一改, 由於我們的item會隨著todolist而變化, 因此需要將函式參數順序稍微修改一下成「job(item: str, name: str, action: str)」。

另外在於multiprocess的部份, 我們原先使用的是「starmap」接受多參數的模式, 但經上述演示之後覺得對於大數據的處理不太妥當, 因此我們可以更換成「map(func, iterable[, chunksize])」, 他們的差異主要在於

import multiprocessing
import time
import random
import sys
from functools import partial

def job(item: str, name: str, action: str):
"""工作內容

Args :
item (str): 工作的項目 [可變]
name (str): 工作名稱 [固定]
action (str): 動作 [固定]

Retruns:
None
"""
secs = random.random()
result = f'{name} 正在 {action} {item} 花費了 {secs} 秒'
return result

if __name__ == "__main__":
# 固定的參數
name = '食品加工廠'
action = '製作'

# 主程序提供的待辦事項清單
# todo_list = ['熱狗', '炸雞', '薯條', '肉乾']
todo_list = [f"工作{i}" for i in range(1, 10000000)]

num_workers = 24

# 創建一個多進程池,這裡使用3個進程
with multiprocessing.Pool(processes=num_workers) as pool:
start_time = time.time()
job_func = partial(job, name=name, action=action)
end_time = time.time()

use_bytes = sys.getsizeof(job_func)
use_mb = use_bytes / 1048576
print(f'渲染參數花費的時間: {end_time - start_time} 秒, 耗用的記憶體: {use_mb} MB')

results = pool.map(job_func, todo_list)
for result in results:
print(result)
raw-image

乍看之下是不是會誤以為花費更久的時間了呢? 請仔細看一下它的數字是否怪怪的, 有負數的出現…, 這是科學記號, 代表是一個非常小的數字, 也就是幾乎沒有耗損的過程, 這面對於大數據的處理, 相對能夠帶來極大的效能增幅。

結語

上述的例子仍有一些缺陷, 雖然實際上仍是以multiprocess的方式並行處理我們的運算, 但必須等待全部的工作完成後, 才回到主線程, 這對於我們跟蹤程式進度的應用會稍微不利, 不過沒關係, 我們後續也會針對這個部份進行重點分享, 歡迎持續追蹤, 讓我們一起探究軟體開發的大小事。

學習軟體開發的路上常常苦於網路資訊爆炸嗎? 教學何其多,但卻遇到無法明確選擇的困境呢? 歡迎加入「🔒 阿Han的軟體心法實戰營」, 這裡不給您冗餘的雜訊, 單刀直入直接送您業界開發重點, 避開選擇障礙的困境, 讓您獲得業界標準的開發起手式, 成為Top 1的頂尖人才。

109會員
249Content count
哈囉,我是阿Han,是一位 👩‍💻 軟體研發工程師,喜歡閱讀、學習、撰寫文章及教學,擅長以圖代文,化繁為簡,除了幫助自己釐清思路之外,也希望藉由圖解的方式幫助大家共同學習,甚至手把手帶您設計出高品質的軟體產品。
留言0
查看全部
發表第一個留言支持創作者!
阿Han的沙龍 的其他內容
我們在「【💊 Python的解憂錦囊】如何將dict轉成json並儲存」有介紹過如何將dict型態的資料轉換成json,除了json之外, 另一個耳熟能詳的資料交換格式就是csv了, 我們常常會將csv讀進來, 並使用預先設計的@dataclass來存放, 如此一來實際運行時, 更能夠貼近於我
關於json的資料交換格式請參考「【程式語言 - Javascript】輕量資料格式 JSON」, 我們常常會在使用套件的過程中發現回傳值的型態都會有「dict」的蹤跡, 為什麼呢? 因為動態、彈性、靈活, 不需要預先定義類別來明確指定每個欄位的內容, 但缺點就是文件必須寫清楚內容物是哪些, 否
「functools.partial」是Python中的一個標準函式庫,它可以讓我們基於既有的函式封裝成多種不同用途的函式,就如同上圖所示,我們設計了一個乘法(multiply)的函數,使用了partial讓函數的參數「c」固定下來依據用途不同變化出「double」、「triple」,這樣一來我
最近正好在研究「silero-vad」這套工具, 但根據官方教學,預設的載入方式會從網路上進行下載模型的動作: model, utils = torch.hub.load(repo_or_dir='snakers4/silero-vad',
我們在「【💎Python 軍火庫 - devpi】pip install…等太久了嗎🤔? 您需要來點緩存機制」有介紹過pypi套件緩存的架設方式, 那架設好了之後, 我們在下載的部份會有一層快取及代理的前哨站, 但假如我們的套件不在pypi平台時怎麼辦呢? 就像torch的套件就必須仰賴外部的來
相信玩過Python一陣子的朋友應該曾經都遇到過套件版本衝突的問題吧…, 這實在是很惱人, 但如果我們能夠快速的檢驗我們所安裝的套件是否如我們所預期的版本, 該有多好, 如此一來能夠讓自己更加安心一些, 那麼今天將提供兩種方法讓我們來檢查一番。 列出所有套件及版本 簡單且暴力。 pip lis
我們在「【💊 Python的解憂錦囊】如何將dict轉成json並儲存」有介紹過如何將dict型態的資料轉換成json,除了json之外, 另一個耳熟能詳的資料交換格式就是csv了, 我們常常會將csv讀進來, 並使用預先設計的@dataclass來存放, 如此一來實際運行時, 更能夠貼近於我
關於json的資料交換格式請參考「【程式語言 - Javascript】輕量資料格式 JSON」, 我們常常會在使用套件的過程中發現回傳值的型態都會有「dict」的蹤跡, 為什麼呢? 因為動態、彈性、靈活, 不需要預先定義類別來明確指定每個欄位的內容, 但缺點就是文件必須寫清楚內容物是哪些, 否
「functools.partial」是Python中的一個標準函式庫,它可以讓我們基於既有的函式封裝成多種不同用途的函式,就如同上圖所示,我們設計了一個乘法(multiply)的函數,使用了partial讓函數的參數「c」固定下來依據用途不同變化出「double」、「triple」,這樣一來我
最近正好在研究「silero-vad」這套工具, 但根據官方教學,預設的載入方式會從網路上進行下載模型的動作: model, utils = torch.hub.load(repo_or_dir='snakers4/silero-vad',
我們在「【💎Python 軍火庫 - devpi】pip install…等太久了嗎🤔? 您需要來點緩存機制」有介紹過pypi套件緩存的架設方式, 那架設好了之後, 我們在下載的部份會有一層快取及代理的前哨站, 但假如我們的套件不在pypi平台時怎麼辦呢? 就像torch的套件就必須仰賴外部的來
相信玩過Python一陣子的朋友應該曾經都遇到過套件版本衝突的問題吧…, 這實在是很惱人, 但如果我們能夠快速的檢驗我們所安裝的套件是否如我們所預期的版本, 該有多好, 如此一來能夠讓自己更加安心一些, 那麼今天將提供兩種方法讓我們來檢查一番。 列出所有套件及版本 簡單且暴力。 pip lis
你可能也想看
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
我們將探索函式的定義和調用,這是程式設計中非常重要且強大的概念,它可以將大型程式切割成小的、可重複使用的函式。讓我們一起來了解吧!函式的定義、呼叫和返回值是學習函式的核心。
Thumbnail
探索Python學習筆記中列表的建立、存取和常用方法。從使用中括號定義列表到了解索引、新增、刪除、修改等操作,並介紹append、remove、count等常用方法。
Thumbnail
在本篇Python學習筆記中,我們探討了字典的建立與存取,以及常用方法,字典是一種強大的資料型態,透過key和value的對應關係存儲和取得資料,我們學會了建立字典、存取資料、新增/修改/刪除項目,以及取得key和value的方法,字典是Python中不可或缺的工具!
Thumbnail
我們探討了while迴圈的使用,不同於for迴圈,while迴圈以條件式判斷為基礎,而非限定重複次數。我們介紹了使用break語句強制結束迴圈,以及使用continue語句跳過特定程式碼並返回迴圈開頭,同時,我們提及了無窮迴圈的概念,強調了在迴圈中必須更改迴圈變數的值,以避免無窮迴圈的發生。
Thumbnail
經濟是國家的命脈,社稷重點無可厚非,國際情勢不好、經濟危機出現時,國家資源救市,穩定法人、投資人信心,維持正常的金融機轉,讓國家度過危機,👍值得嘉許,只是這次國安基金護盤的故事,讓人百般尋味。 台股去年創下18650破紀錄新高,隨著國際局勢一起回檔,國安基金決定進場護盤: 第一:當時股市萬八,不是
Thumbnail
在最近動盪的銀行冒險記裡,開始出現銀行倒閉的新聞,或是接近倒閉被接管,💣一個個炸彈,在主政者的輔助下,細細呵護的灌溉、包紮,給予營養補給,🇺🇸美洲的銀行危機,暫時告一段落。 後來出現了另一個危機,CS瑞士信貸,不是CS絕對武力,Credit Suisse,規模同比有過之而無不及,好像一顆加大的
Thumbnail
這一年來,得到最大的收穫就是「做自己」! 最浪費時間的事是什麼呢?就是拿自己和別人比較🥹 嘿親愛的,我們都是獨特且美麗的存在❤️
Thumbnail
今天的領受是在上個禮拜每週五都會去上的照顧者關懷工作坊, 課中領受到的!! (哈哈只剩下禮拜最後一堂課了) 感謝主也可以給我些思考, 和這個領受❤️🤗 這週應該算是課堂裡 塞最多內容的一課了, 哈哈我後來都有點精神渙散想睡了🤣 辛苦老師了!!! 主要講到兩個主題: 步向正面思考、一些用藥知識 和
Thumbnail
第一家公司產品的由專業團隊設計和研發的,因此品質得到保證。提供豐富的資源,包括在線健康諮詢服務和健康資訊,幫助顧客了解如何使用產品和實現健康目標。該公司的產品具有良好的可負擔性。通過線上購買,顧客可以輕鬆訂購所需的產品,並且該公司的價格也相對實惠。
《女性性需求第一定律》 為什麼有些女生總是會把性行為這件事無限往後延? 今天史提將從紅藥丸演化博弈心理學的角度 ,來探討一下這個問題🤨 想像你是一個妹子,有一個男的每天照三餐都會給妳鮮花素果🍉🍑🥝因為他想追妳,妳能有的選項: 1.跟他交往並啪啪啪🤨 2.不跟他交往也不啪啪啪🤔 = ;
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
我們將探索函式的定義和調用,這是程式設計中非常重要且強大的概念,它可以將大型程式切割成小的、可重複使用的函式。讓我們一起來了解吧!函式的定義、呼叫和返回值是學習函式的核心。
Thumbnail
探索Python學習筆記中列表的建立、存取和常用方法。從使用中括號定義列表到了解索引、新增、刪除、修改等操作,並介紹append、remove、count等常用方法。
Thumbnail
在本篇Python學習筆記中,我們探討了字典的建立與存取,以及常用方法,字典是一種強大的資料型態,透過key和value的對應關係存儲和取得資料,我們學會了建立字典、存取資料、新增/修改/刪除項目,以及取得key和value的方法,字典是Python中不可或缺的工具!
Thumbnail
我們探討了while迴圈的使用,不同於for迴圈,while迴圈以條件式判斷為基礎,而非限定重複次數。我們介紹了使用break語句強制結束迴圈,以及使用continue語句跳過特定程式碼並返回迴圈開頭,同時,我們提及了無窮迴圈的概念,強調了在迴圈中必須更改迴圈變數的值,以避免無窮迴圈的發生。
Thumbnail
經濟是國家的命脈,社稷重點無可厚非,國際情勢不好、經濟危機出現時,國家資源救市,穩定法人、投資人信心,維持正常的金融機轉,讓國家度過危機,👍值得嘉許,只是這次國安基金護盤的故事,讓人百般尋味。 台股去年創下18650破紀錄新高,隨著國際局勢一起回檔,國安基金決定進場護盤: 第一:當時股市萬八,不是
Thumbnail
在最近動盪的銀行冒險記裡,開始出現銀行倒閉的新聞,或是接近倒閉被接管,💣一個個炸彈,在主政者的輔助下,細細呵護的灌溉、包紮,給予營養補給,🇺🇸美洲的銀行危機,暫時告一段落。 後來出現了另一個危機,CS瑞士信貸,不是CS絕對武力,Credit Suisse,規模同比有過之而無不及,好像一顆加大的
Thumbnail
這一年來,得到最大的收穫就是「做自己」! 最浪費時間的事是什麼呢?就是拿自己和別人比較🥹 嘿親愛的,我們都是獨特且美麗的存在❤️
Thumbnail
今天的領受是在上個禮拜每週五都會去上的照顧者關懷工作坊, 課中領受到的!! (哈哈只剩下禮拜最後一堂課了) 感謝主也可以給我些思考, 和這個領受❤️🤗 這週應該算是課堂裡 塞最多內容的一課了, 哈哈我後來都有點精神渙散想睡了🤣 辛苦老師了!!! 主要講到兩個主題: 步向正面思考、一些用藥知識 和
Thumbnail
第一家公司產品的由專業團隊設計和研發的,因此品質得到保證。提供豐富的資源,包括在線健康諮詢服務和健康資訊,幫助顧客了解如何使用產品和實現健康目標。該公司的產品具有良好的可負擔性。通過線上購買,顧客可以輕鬆訂購所需的產品,並且該公司的價格也相對實惠。
《女性性需求第一定律》 為什麼有些女生總是會把性行為這件事無限往後延? 今天史提將從紅藥丸演化博弈心理學的角度 ,來探討一下這個問題🤨 想像你是一個妹子,有一個男的每天照三餐都會給妳鮮花素果🍉🍑🥝因為他想追妳,妳能有的選項: 1.跟他交往並啪啪啪🤨 2.不跟他交往也不啪啪啪🤔 = ;