Python 2.7: "multiprocessing.Pool"出现“无法启动新线程”错误。

5

这是我的情况。代码与文档中的示例几乎相同:

from multiprocessing import Pool
import numpy as np

def grad(x0, y): return 0 # does some computational-heavy work actually

if __name__ == '__main__':

    class UnrollArgs:
        def __init__(self, func):
            self.func = func

        def __call__(self, args):
            return self.func(*args)

    def batch_grad(x0, y, processes=4):
        g = Pool(processes).map(UnrollArgs(grad), [(x0, yi) for yi in y])
        return np.sum([gi for gi in g], axis=0) / len(y)

我传递给batch_grad的y有50个元素,Pool.map引发错误:
错误:无法启动新线程
从Google上了解到,这通常是由于尝试启动太多线程而导致的。也许只是我觉得,但我认为关于multiprocessing.Pool的文档有点不完整。特别是,我不知道如何控制应该启动的线程数。在Pool类的文档中甚至没有提到“线程”一词。
multiprocessing.Pool的整数参数是要启动的进程数,而不是线程数。
那么我该怎么办呢?
更新:值得注意的是,并非每次运行代码都会引发错误。

@aganders3:这是我的完整示例,唯一的例外是grad正在进行一些计算密集型的工作。错误是从Pool类的map函数内部引发的。我没有使用线程。 - theV0ID
源代码 来看,似乎是在 Python 解释器启动期间,在 PyThread_start_new_thread 中创建线程时出现了低级别的失败(它是一个系统相关的线程库的包装器)。可能是内存不足导致的? - Cong Ma
@aganders3:是的,确实如此。因为没有启动任何线程。请注意我的更新,错误不会在每次运行代码时都出现。 - theV0ID
@CongMa:是的,可能是内存不足了。但是,我如何控制(甚至降低)每个进程生成的线程数呢? - theV0ID
2
@theV0ID 我认为这个错误是由multiprocessing在启动Python解释器本身时生成的,当有多个解释器进程被生成时。在这种情况下,您无法控制解释器启动的实际线程数量,至少不能通过multiprocessing。但是我可能错了。我不是CPython内部的专家。 - Cong Ma
显示剩余11条评论
1个回答

3
我认为问题源于生成了许多“池”。这个错误很奇怪,我认为@ChongMa是正确的,它与Python解释器本身无法生成线程有关。听起来我的评论建议对你可能有用,所以我在这里将其重新发布为答案。
请尝试以下修复方法: a)使用“Pool.close()”方法让每个“池”知道它不会再获得任何工作:
def batch_grad(x0, y, processes=4):
    pool = Pool(processes)
    g = pool.map(UnrollArgs(grad), [(x0, yi) for yi in y])
    pool.close()
    return np.sum([gi for gi in g], axis=0) / len(y)

b) 重复使用一个Pool来处理所有任务 - 将Pool对象传递到您的batch_grad函数中,而不是一些进程的数量:

def batch_grad(x0, y, pool=None):
    if pool is None:
        pool = Pool(4)
    g = pool.map(UnrollArgs(grad), [(x0, yi) for yi in y])
    return np.sum([gi for gi in g], axis=0) / len(y)

# then call your function like so
p = Pool(4)
batch_grad(your_x0, your_y, p)

希望这对你长期有所帮助。

再次感谢,我会在进行更多测试后“接受”您的答案。 - theV0ID

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接