【问题标题】:python multiprocessing, big data turn process into sleeppython多处理,大数据让进程进入睡眠状态
【发布时间】:2015-09-20 12:09:58
【问题描述】:

我正在使用 python 2.7.10。 我读了很多文件,将它们存储到一个大列表中,然后尝试调用多处理并将大列表传递给这些多进程,以便每个进程都可以访问这个大列表并进行一些计算。

我正在使用这样的池:

def read_match_wrapper(args):
    args2 = args[0] + (args[1],)
    read_match(*args2)

 pool = multiprocessing.Pool(processes=10)
 result=pool.map(read_match_wrapper,itertools.izip(itertools.repeat((ped_list,chr_map,combined_id_to_id,chr)),range(10)))
 pool.close()
 pool.join()

基本上,我将多个变量传递给“read_match”函数。为了使用 pool.map,我编写了“read_match_wrapper”函数。我不需要从这些过程中返回任何结果。我只是想让他们跑完。

当我的数据列表“ped_list”非常小时,我可以完成整个过程。当我加载所有数据(例如 10G)时,它生成的所有多进程都显示“S”并且似乎根本不起作用..

我不知道你可以通过池访问多少数据是否有限制? 我真的需要帮助!谢谢!

【问题讨论】:

  • read_match的代码是什么?
  • 您能否检查itertools.izip() 部分是否返回了正确的值?如果您的数据真的是 10G,使用repeat(),它可能会变得更糟,并且可能会消耗太多内存。
  • 是的,我认为内存是这里的问题。每次它产生一个进程时,都会复制内存。而集群负担不起!

标签: python multiprocessing bigdata sleep pool


【解决方案1】:

来自多处理编程指南:

避免共享状态

As far as possible one should try to avoid shifting large amounts of data between processes.

您所遭受的典型症状是管道已满且未排干。

Pool 使用的 Python multiprocessing.Pipe 存在一些设计缺陷。它基本上在更像流对象的 OS 管道上实现了一种面向消息的协议。

结果是,如果你通过管道发送一个太大的对象,它就会被塞满。发送者将无法向其添加内容,接收者将无法将其耗尽,因为它在等待消息结束时被阻塞。

证明你的工人正在睡觉等待那个永远不会到达的“胖”消息。

ped_list 是否包含文件名或文件内容?

在第二种情况下,您宁愿发送文件名而不是内容。工作人员可以通过简单的 open() 自行检索内容。

【讨论】:

  • 我从其他帖子中注意到这一点,stackoverflow.com/questions/14124588/…。我应该把我的 ped_list 变成 multiprocessing.Array。但我不知道该怎么做,因为它是一个列表列表..multiprocessing.Array 似乎只采用非常简单的格式
  • 无论您使用什么方法来共享 ped_list,如果没有非常很好地实现,它仍然会很慢并且会出现死锁。问题的真正解决方案仍然是建议的解决方案。无需在 ped_list 中加载文件内容,只需加载文件名并让子工作人员自行加载文件。另一个和你一模一样的问题:stackoverflow.com/questions/27253666/…
  • 您会注意到,在这种情况下,管道是一个真正的瓶颈,因此速度会有所提高。在 Unix 系统上,它的大小通常限制为 32Mb。你想通过它填充 10Gb :)
【解决方案2】:

我宁愿使用队列,而不是使用pool.map。您可以生成所需数量的进程并为输入分配一个队列:

n = 10 #number of processes
tasks = multiprocessing.Queue()

for i in range(n): #spawn processes
    multiprocessing.Process(target = read_match_wrapper, args = tasks)
for element in ped_list:
    tasks.put(element)

这样,您的队列从一侧填充,同时从另一侧清空。也许有必要在进程开始之前将一些东西放入队列中。当队列为空或引发 Queue.empty-exception 时,它们可能会在不执行任何操作的情况下结束。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 2011-05-12
    相关资源
    最近更新 更多