Python3多处理:内存分配错误

时间:2017-09-25 14:28:45

标签: python-3.x python-multiprocessing

我知道这个问题已被问过很多次,但答案不适用。 这是在StackoverFlow上使用多处理的并行循环的answer one

import multiprocessing as mp

def processInput(i):
    return i * i

if __name__ == '__main__':
    inputs = range(1000000)
    pool = mp.Pool(processes=4)
    results = pool.map(processInput, inputs)
    print(results)

此代码工作正常。但是,如果我将范围增加到1000000000,我的16GB Ram将完全填满,我得到 [Errno 12]无法分配内存。似乎 map 函数启动尽可能多的进程。如何限制并行进程的数量?

2 个答案:

答案 0 :(得分:1)

pool.map函数按照您的指示启动4个进程(在行process = 4中,您指示池可以使用多少进程来执行逻辑)。

然而,这个实现存在不同的问题。 pool.map函数将返回一个对象列表,在这种情况下是它的数字。 数字不像ANSI-C中的int-s那样具有开销并且不会溢出(例如,当在32位上达到2 ^ 31 + 1时转向-2 ^ 31)。 python列表也不是数组,并且会产生开销。

更具体地说,在python 3.6上,运行以下代码将揭示一些开销:

>>>import sys
>>>t = [1,2,3,4]
>>>sys.getsizeof(t)
96
>>>t = [x for x in range(1000)]
>>>sys.getsizeof(t)
9024

因此,这意味着小列表上的每个数字为24个字节,大型列表上为~9个字节。 因此,对于列表大小为10 ^ 9,我们得到大约8.5GB

编辑:1。正如tfb所提到的,这甚至不是基础Number对象的大小,只是指针和列表开销,这意味着我在原始答案中没有考虑到更多的内存开销。

  1. Windows上的默认python安装是32位(您可以获得64位安装,但需要检查python网站中所有可用下载的部分),所以我假设您使用的是32位安装。 / LI>

答案 1 :(得分:0)

range(1000000000)创建一个10 ^ 9 int的列表。这大约是8GB(64位系统上每int 8个字节)。然后,您尝试处理此操作以创建另一个10 ^ 9 int的列表。一个真正非常聪明的实现可能能够在16GB的机器上实现这一点,但它基本上是一个失败的原因。

在Python 2中,您可以尝试使用xrange,这可能会有所帮助,也可能没有帮助。我不确定Python 3的等价物是什么。