python multiprocessing.pool.map,将参数传递给衍生进程

时间:2016-07-14 20:47:16

标签: python multiprocessing python-multiprocessing

def content_generator(applications, dict):
    for app in applications:
        yield(app, dict[app])

with open('abc.pickle', 'r') as f:
    very_large_dict = pickle.load(f)
all_applications = set(very_large_dict.keys())

pool = multiprocessing.Pool()
for result in pool.imap_unordered(func_process_application, content_generator(all_applications, very_large_dict)):
    do some aggregation on result

我有一个非常大的字典,其键是字符串(应用程序名称),值是有关应用程序的信息。由于应用程序是独立的,我想使用多处理来并行处理它们。当字典不是很大但字典太大时所有python进程都被杀死时,并行化就可以工作。我使用dmesg检查出了什么问题,发现它们因机器内存不足而被杀死。当池进程正在运行时我做了top并发现它们都占用了相同数量的常驻内存(RES),这都是3.4G。这让我感到困惑,因为它似乎已经将整个词典复制到了衍生过程中。我以为我打破了字典,只通过dict[app]代替dict来传递与生成过程相关的内容。对我做错了什么的想法?

1 个答案:

答案 0 :(得分:1)

评论变得无法遵循,所以我在这里重复评论:

在Linux-y系统上,新进程由fork()创建,因此在创建时获取整个父进程地址空间的副本。它写了#34;复制#34;虚拟"更多的是"虚拟"复制而不是"真实"复制,但仍然... ;-)首先,尝试在创建巨型数据结构之前创建Pool。然后子进程将继承一个小得多的地址空间。

然后回答一些问题:

  

所以在python 2.7中,没有办法产生一个新进程?

在Linux-y系统上,没有。能够使用"产生"这些是在Python 3.4中首次添加的。在Windows系统上," spawn"一直是唯一的选择(Windows上没有fork()。)

  

大字典作为参数传递给函数而我   只能在此功能中创建池。我怎么能够   在大词典之前创建池

这很简单:将这两行作为程序中的前两行:

import multiprocessing
pool = multiprocessing.Pool()

您可以随时创建池(只要它存在某个时间,然后才能实际使用它),并且工作进程将在当时继承整个地址空间 / em>调用Pool构造函数。

另一个建议

如果你在创建dict之后没有改变dict,请尝试使用它:

def content_generator(dict):
    for app in dict:
        yield app, dict[app]

这样你也不必实现一大堆钥匙。或者,甚至更好(如果可能的话),跳过所有这些并直接遍历项目:

for result in pool.imap_unordered(func_process_application, very_large_dict.iteritems()):