2016-08-22 55 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