2011-11-30 123 views
1

我一直百思不得其解这个现在整整一夜......蟒蛇平行POPEN

makeflags = ['--prefix=/usr','--libdir=/usr/lib'] 
rootdir='/tmp/project' 
ps = set() 

def configModule(m): 
    print m 
    return Popen(["./autogen.sh"] + makeflags, cwd=rootdir+"/"+m) 

for module in ['mod1','mod2','mod3' ... 'mod10']: 
    ps.add(configModule(module)) 

os.wait() 

我期待它会启动10个进程和并行执行./autogen.sh。但是,我观察到的是,第一个configModule似乎在函数被调用后立即退出。我只看到“print m”语句,但不是“mod1”中的./autogen.sh的实际输出。但是,在mod4之后,代码开始并行运行。我可以看到CPU利用率很高,并且输出已经在不同的模块文件夹中生成。

任何想法为什么前几个模块不产生./autogen.sh结果?

P.S.如果我以串行方式运行此代码(即使用subprocess.call而不是Popen),它可以正常工作。

+0

我还试图用多模块,不幸的是,我可以克服unpickle问题,因为我试图启动的进程池的一类... – Patrick

+0

我认为这是一个复制/粘贴错误,但是不应该将'm'传递给'Popen'调用而不是'module'? – jro

+0

@jro是啊,好眼睛!我修复了错字。 – Patrick

回答

1

您的代码适用于我,并应启动所有进程。你没有给我们太多的工作:什么行为不同?

您不会将输出重定向到您粘贴的代码中,因此您可能会看到子视图的流stderr。有一件事是:

os.wait() 

...只会等待1个进程。您可能想要使用Popen的返回值,并在每个子进程上调用waitcommunicate。然后,您可以另外使用返回值,以确保他们都成功地死去:

# Instead of os.wait(): 
for p in ps: 
    p.wait() 
    print 'A process returned:', p.returncode 

希望,他们都应该是0,如果一切正在恢复正常。

+0

如果3个数据流中没有一个被重定向到PIPE,那么'communic()'就没有用处。 'wait()'应该在这里就足够了... – glglgl

+0

啊,我想我可能知道现在发生了什么......因为这是一个非阻塞的调用,所以在任务完成之前我看到了“print m”。 ./autogen.sh可能已经排队并仍在使用它。我会再等一会儿,看看所有文件夹是否都正常。 – Patrick

+0

@glglgl:在这种情况下,'communic'变成等同于'wait'。尽管如此。 – Thanatos

1

与DA虚拟系统调用工程的similiarly建立程序按预期:

from subprocess import * 

makeflags = ['--prefix=/usr','--libdir=/usr/lib'] 
rootdir='/tmp/project' 
ps = dict() 

def configModule(m): 
    print m 
    p = Popen("echo start %s; sleep %d; echo finish %s" % (m, 10-m, m), shell=True) 
    #p.m = m 
    return p 

for module in range(10): 
    ps[configModule(module)] = module 

while ps: 
    done = set() 
    for p in ps: 
     s = p.poll() 
     if s is not None: 
      print "Module %d: %d" % (ps[p], s) 
      done.add(p) 
    for p in done: 
     del ps[p] 
#os.wait() 

你肯定输出真正缺少的,或只是延迟?

BTW:

for module in ('mod%d' % i for i in range(1, 11)): 

是更优雅...