我正在使用networkx
(网络分析库)进行一些缓慢的计算,我正在尝试使用Pool worker来使其更快一些。计算是独立的,因此应该相对简单地并行化它们。
def computeInfoPooled(G,num_list):
pool=Pool(processes=4)
def f(k):
curr_stat={}
curr_stat[k]=slow_function(k,G)
return curr_stat
result = pool.map(f,num_list)
return result
现在,我在控制台中运行了以下内容:
computed_result=computeInfoPooled(G)
我希望这段代码可以创建4个进程,并在不同进程中使用num_list的每个项目(一个数字)调用f。如果num_list包含4个以上的数字(在我的情况下大约是300个),那么它将同时运行4并将其余数据排队,直到其中一个池化工作完成。
当我运行我的代码时发生的事情是许多python.exe被生成(或分叉,不确定发生了什么)并且它似乎创建了无限多个进程,因此我不得不拔掉我的机器。
任何想法我做错了什么以及如何解决它?
答案 0 :(得分:1)
在Windows上,您需要
if __name__ == '__main__':
computed_result = computeInfoPooled(G)
使您的脚本无需启动叉炸弹就可导入。 (请阅读标题为“安全导入主模块”的部分in the docs。
另请注意,在Windows上,您可能无法使用交互式解释器中的多处理模块。 请参阅top of the docs附近的警告:
此程序包中的功能要求 main 模块 可由儿童进口。编程指南中对此进行了介绍 但是值得指出这里。这意味着一些例子, 例如多处理.Pool示例将不起作用 互动口译员。 (我的重点。)
而是将脚本保存到文件中,例如script.py
并从命令行运行它:
python script.py
此外,您需要pool.map
的参数可以选择。
函数f
需要在模块级别定义(不在computeInfoPooled
内部以便可以选择:
def f(k):
curr_stat = slow_function(k, G)
return k, curr_stat
def computeInfoPooled(G, num_list):
pool = Pool(processes=4)
result = pool.map(f, num_list)
return dict(result)
if __name__ == '__main__':
computed_result = computeInfoPooled(G)
顺便说一下,如果f
返回一个字典,那么pool.map(f, ...)
将返回一个字典列表。我不确定这是你想要的,特别是因为每个dict只有一个键值对。
相反,如果您让f
返回一个(键,值)元组,那么pool.map(f, ...)
将返回一个元组列表,然后您可以将其转换为带有dict(result)
的字典。
答案 1 :(得分:0)
Windows编程指南下的文档对此进行了解释。
根据您的平台,每个流程可能必须启动一个全新的解释器并import
您的模块才能启动f
函数。 (在Windows上,总是必须这样做。)当import
模块运行时,所有顶级代码都会运行,其中包含行computed_result=computeInfoPooled(G)
,它会创建一个全新的4个进程池等等。
你可以像处理任何其他情况一样解决这个问题,你希望同一个文件既可作为模块导入又可作为脚本运行:
def computeInfoPooled(G,num_list):
pool=Pool(processes=4)
def f(k):
curr_stat={}
curr_stat[k]=slow_function(k,G)
return curr_stat
result = pool.map(f,num_list)
return result
if __name__ == '__main__':
computed_result=computeInfoPooled(G)
从您的编辑和评论中,您似乎期望从交互式解释器调用computeInfoPooled(G)
将解决该问题。相同的链接文档部分详细解释了为什么不起作用,Introduction顶部的一个重要说明直接说:
此程序包中的功能要求子项可以导入 main 模块。这在编程指南中有所涉及,但值得在此指出。这意味着一些示例,例如multiprocessing.Pool示例在交互式解释器中不起作用。
如果您想了解为什么会这样,您需要阅读链接的文档(您还需要了解import
,pickle
和multiprocessing
的方式所有的工作)。