首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将参数传递给生成的进程。

问将参数传递给生成的进程。
EN

Stack Overflow用户
提问于 2016-07-14 20:47:15
回答 1查看 1.2K关注 0票数 4
代码语言:javascript
复制
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。对我做错了什么有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-14 21:24:41

这些评论正变得不可能被理解,所以我在这里贴上了我的重要评论:

在Linux-y系统上,新进程由fork()创建,因此在创建父进程地址空间时获取整个父进程地址空间的副本。它是“写上的复制”,所以与其说是“真实的”拷贝,不如说是“虚拟的”副本,但是.-)首先,在创建巨大的数据结构之前尝试创建您的Pool。然后子进程将继承一个更小的地址空间。

然后回答一些问题:

所以在python2.7中,没有办法产生一个新的过程?

在Linux-y系统上,没有。第一次在Python3.4中添加了在这些文件上使用“派生”的功能。在Windows系统上,“派生”一直是唯一的选择(在Windows上没有fork() )。

大字典作为参数传递给函数,我只能在这个函数中创建池。我怎样才能在大字典之前创建池呢?

如下所示:使这两行成为程序中的前两行:

代码语言:javascript
复制
import multiprocessing
pool = multiprocessing.Pool()

您可以在任何时候创建池(只要它在实际使用之前就存在),并且在调用Pool构造函数时,工作进程将继承整个地址空间。

另一项建议

如果在创建dict之后没有对其进行变异,请尝试使用以下方法:

代码语言:javascript
复制
def content_generator(dict):
    for app in dict:
        yield app, dict[app]

那样的话,你也不必把一套巨大的钥匙变成现实。或者,更好的(如果可能的话)跳过所有这些,直接迭代这些项:

代码语言:javascript
复制
for result in pool.imap_unordered(func_process_application, very_large_dict.iteritems()):
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38383981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档