2016-08-22 141 views
1

我試圖使我的熊貓計算的昂貴部分平行於加速的東西。使用池的Python多處理進行遞歸干擾

我已經成功地使Multiprocessing.Pool工作,一個簡單的例子:在這裏

import multiprocessing as mpr 
import numpy as np 

def Test(l): 
    for i in range(len(l)): 
    l[i] = i**2 
    return l 

t = list(np.arange(100)) 
L = [t,t,t,t] 
if __name__ == "__main__": 
    pool = mpr.Pool(processes=4) 
    E = pool.map(Test,L) 
    pool.close() 
    pool.join() 

沒有問題。現在我自己的算法是一個比較複雜一點,我不能在這裏張貼在其充滿榮耀和可畏,所以我會用一些僞代碼勾勒出的東西,我在那裏做什麼:

import pandas as pd 
import time 
import datetime as dt 
import multiprocessing as mpr 
import MPFunctions as mpf --> self-written worker functions that get called for the multiprocessing 
import ClassGetDataFrames as gd --> self-written class that reads in all the data and puts it into dataframes 

=== Settings 

=== Use ClassGetDataFrames to get data 

=== Lots of single-thread calculations and manipulations on the dataframe 

=== Cut dataframe into 4 evenly big chunks, make list of them called DDC 

if __name__ == "__main__": 
    pool = mpr.Pool(processes=4) 
    LLT = pool.map(mpf.processChunks,DDC) 
    pool.close() 
    pool.join() 

=== Join processed Chunks LLT back into one dataframe 

=== More calculations and manipulations 

=== Data Output 

當我運行此腳本時,會發生以下情況:

  1. 它讀取數據。

  2. 它執行所有計算和操作,直到池語句。

  3. 突然它再次讀入數據,四倍。

  4. 然後它同時進入主腳本四倍。

  5. 整個事情遞歸地級聯,並走向haywire。

我已經閱讀過,如果你不小心,這可能會發生,但我不知道它爲什麼發生在這裏。我的多處理代碼受所需的名稱 - 主 - 語句(我在Win7 64上)保護,它只有4行,它有close和join語句,它調用一個定義的worker函數,然後調用第二個worker函數一個循環,就是這樣。據我所知,它應該創建具有四個進程的池,從導入的腳本調用四個進程,關閉池並等待一切完成,然後繼續執行腳本。在一個旁註中,我首先在同一個腳本中使用了工作函數,行爲是一樣的。而不是僅僅在游泳池中做什麼,它似乎重新啓動整個劇本四倍。

任何人都可以啓發我什麼可能會導致此行爲?我似乎錯過了一些關於Python多處理行爲的重要理解。

另外我不知道它是否重要,我在一臺位於我公司主機上的虛擬機上。

我必須使用單個進程而不是池嗎?

回答

1

我設法通過將整個腳本簡化爲if __name__ == "__main__":-聲明來實現它,而不僅僅是多處理部分。

+1

我認爲最好的辦法是將你的代碼構造成一個'main'函數(並且可能將這個函數分成更小的函數......以避免有100行函數執行大量的工作),然後代碼的唯一不是類/函數/變量定義的部分的形式是:'if __name__ =='__main__':main()'。這確保多處理按預期工作。還要注意,全局變量查找速度慢,所以將代碼放入函數中會提高性能。 – Bakuriu