![](/img/trans.png)
[英]multiprocessing in python (going from a for loop to multiprocessing for loop)
[英]Python Multiprocessing Loop
我希望使用multiprocessing
來加速緩慢的循環。 但是,從我對多處理示例的了解中,我不確定這種實現是否是好的實踐,可行或可能的。
循環大致分為兩個部分: data ingestion
和data processing
。 我希望在處理正在進行時開始進行數據攝取的下一部分,因此數據將盡快可用。
偽代碼:
d = get_data(n)
for n in range(N):
p = process_data(d)
d = get_data(n+1) #prepare data for next process loop
提前致謝。
如您所說,多處理基本上就是調度和收集工作。 正如您所闡明的,您基本上希望process_data
和get_data
並行工作。
這是我為您提供的解決方案
import multiprocessing as mp
# create pool for dispatching work
pool = mp.Pool()
# call your functions asynchronously
process_data_process = pool.apply_async(process_data, (d,))
get_data_process = pool.apply_async(get_data, (n+1,))
# After your functions are dispatched, wait for results
process_data_result = process_data_process.get()
get_data_result = get_data_process.get()
# Note: get_data_result will not be fetched till process_data_result is ready
# But that should be fine since you can't start the next batch
# till this batch is done
您可以將其包裝在循環中。 希望這能回答你的問題!
假設您希望有一個線程/進程來提取數據,因為它將是I / O而不是CPU約束。 在將數據傳遞到處理層之前,您只需要對數據進行最少的分析和/或驗證。
讓我們進一步假設您可以完全並行地對每個輸入項進行數據處理。 這些輸入項之間沒有排序或時間/順序依賴性。
在那種情況下,您的任務基本上是“扇出”處理模型的發布者。 您創建一個multiprocessing.Queue對象。 然后創建一個multiprocessing.Pool 。 然后,此初始化代碼成為攝取處理任務(隊列的“生產者”),並且所有進程池都成為消費者,執行處理。
在線有很多示例,第一個鏈接可能有幾個使用此模式。
當然,剩下的問題是您將如何處理結果。
如果他們需要序列化回單個文件,那么顯而易見的方法是創建兩個Queue對象...一個用於工作隊列(攝取過程將其喂入,池進程將其消耗掉),另一個是輸出Queue(池將其饋入其中,然后有一個進程從中消耗掉以將結果一致地寫入輸出中)。 請注意,可以使您的主(安裝)過程多路復用,有時效率很高。 它可以將輸入數據讀取與輸出隊列上的輪詢進行交織以寫出結果。 但是,當然,您也可以啟動另一個專門用於輸出處理的過程。
另一方面,您的結果有可能可以並行編寫,也許是由工作進程並行編寫的。 如果您將結果寫入許多文件,或者將它們作為INSERT或UPDATE語句發布到某些SQL數據庫,或者將結果提供給Hadoop HDFS或Spark DataSet,那么這很好。 有許多形式的輸出適合並行寫入。
您還可能希望將處理層與輸出/結果處理層分離。 可能是您的應用程序將在數據處理層中使用大量進程而在輸出層中使用較少數量的進程進行優化。 (例如,如果每個項目的處理都占用大量CPU,並且您有許多內核,那么當CPU處於空閑狀態時,太多的進程可能會阻塞I / O通道)。
同樣,使用隊列。 它們旨在支持多生產者和多消費者的連貫性。 您擺脫了有關並發鎖定,死鎖和活鎖問題等的擔憂。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.