2012-08-13 192 views
3

我有一个简单的python多处理脚本,它建立了一个试图将工作输出附加到管理器列表的工作者池。该脚本具有3个调用堆栈: - 主调用f1,该调用生成调用另一个函数g1的多个工作进程。当试图调试脚本时(顺便说一句,在Windows 7/64位/ VS 2010/PyTools中),脚本会运行到一个嵌套的进程创建循环中,产生无数的进程。任何人都可以确定原因我确定我错过了一些非常简单的事情。这里是有问题的代码: -python多处理,管理器启动进程spawn循环

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 __”:“块中,并将管理资源作为显式参数传递给工作人员。你试过这样做吗?我的直觉是,当你在模块范围中创建管理器对象时,它与取消过程有关(类似于每次创建新线程时都会产生新的管理器线程,包括创建新管理器线程时) ,因此无限递归)。 – 2012-08-13 16:19:36

+0

我无法重现此代码的问题。它适用于我 - 但我没有使用Windows。 – senderle 2012-08-13 16:41:32

+0

我在Linux上用CPython 2.7.3试过你的例子,它工作。 – user1202136 2012-08-13 16:53:26

回答

5

基本上,sr2222在他的评论中提到的是正确的。从multiprocessing manager docs,它表示____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() 
+0

这就是我开始的地方。但是,将经理和结果放在f1中意味着他们在g1中不可用。取而代之的是一个NameError。 – bsdz 2012-08-13 17:07:11

+0

@bsdz:这就是为什么我通过了'results'(如果你注意到了)。 ...如果你需要'manager',你也可以通过它。 ...或者你可以创建一个类并将它们存储在实例级别。 – Gerrat 2012-08-13 17:09:56

+0

啊,是的,我错过了。必须承认,我希望我不必像这样传递它,但这是如何记录。谢谢! – bsdz 2012-08-13 17:16:55