Python多进程,管理器启动进程生成循环。

4
我有一个简单的Python多进程脚本,它设置了一个工作池,试图将工作输出追加到经理列表中。该脚本有3个调用堆栈:主函数调用f1,该函数生成多个工作进程,这些进程调用另一个函数g1。当尝试在Windows 7/64位/VS 2010/PyTools上调试脚本时,脚本会陷入嵌套进程创建循环,生成无数进程。有人能确定为什么吗?我肯定错过了一些非常简单的东西。以下是有问题的代码:-
import multiprocessing
import logging

manager = multiprocessing.Manager()
results = manager.list()

def g1(x):
    y = x*x
    print "processing: y = %s" % y
    results.append(y)

def f1():
    logger = multiprocessing.log_to_stderr()
    logger.setLevel(multiprocessing.SUBDEBUG)

    pool = multiprocessing.Pool(processes=4)
    for (i) in range(0,15):
        pool.apply_async(g1, [i])
    pool.close()
    pool.join()

def main():
    f1()

if __name__ == "__main__":
    main()

PS: 尝试在主函数中添加multiprocessing.freeze_support(),但没有成功。


1
不确定为什么会导致您看到的问题,但是在文档中使用multiprocess.Manager的示例是在if __name__ == "__main__":块中创建Manager并将托管资源作为显式参数传递给工作者。 您是否尝试过以这种方式处理?我的直觉是,当在模块范围内创建管理器对象时(例如,每次创建新线程时,包括创建新管理器线程时,它会生成一个新的管理器线程),它与取消选择进程有关。 - Silas Ray
我无法复现这段代码的问题。它在我的电脑上正常工作 - 但我没有使用Windows系统。 - senderle
我在Linux上使用CPython 2.7.3尝试了你的示例,它可以正常工作。 - user1202136
肯定是在Windows上使用CPython,但是我想说的是Pytools而不是Pyvot。http://pytools.codeplex.com/ - Blair Azzopardi
1个回答

6
基本上,sr2222在他的评论中提到的是正确的。从多进程管理器文档中可以看出,它说____main____模块必须可以被子模块导入。每个管理器“对象对应一个生成的子进程”,因此每个子进程基本上都在重新导入您的模块(您可以通过在我的修复版本中添加模块范围的打印语句来查看!)...这导致了无限递归。
一种解决方法是将您的管理器代码移动到f1()中:
import multiprocessing
import logging

def g1(results, x):
    y = x*x
    print "processing: y = %s" % y
    results.append(y)

def f1():
    logger = multiprocessing.log_to_stderr()
    logger.setLevel(multiprocessing.SUBDEBUG)
    manager = multiprocessing.Manager()
    results = manager.list()
    pool = multiprocessing.Pool(processes=4)
    for (i) in range(0,15):
        pool.apply_async(g1, [results, i])
    pool.close()
    pool.join()


def main():
    f1()

if __name__ == "__main__":
    main()

那是我开始的地方。然而,将管理器和结果放在f1中意味着它们在g1中不可用。会出现NameError错误。 - Blair Azzopardi
@bsdz:这就是为什么我传递了results(如果你注意到的话)。如果你需要manager,也可以将其传递进去。或者你可以创建一个类并将它们存储在实例级别。 - Gerrat
啊,是的,我错过了那个。必须承认我希望不必像那样传递它,但这就是文档中记录的方式。谢谢! - Blair Azzopardi

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