【问题标题】:python parallel Popenpython并行Popen
【发布时间】:2012-01-09 12:08:17
【问题描述】:

我整晚都在困惑这个问题......

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 结果吗?

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

【问题讨论】:

  • 我也尝试过使用多处理模块,不幸的是,当我尝试在一个类中启动一个进程池时,我可以克服 unpickle 问题...
  • 我认为这是一个复制/粘贴错误,但不应将m 传递给Popen 调用而不是module
  • @jro 是的,好眼睛!我已经修正了错字。

标签: python parallel-processing multiprocessing subprocess


【解决方案1】:

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

您没有在粘贴的代码中重定向输出,因此您可能会看到孩子们的stderr 流。但有一件事是:

os.wait()

...只会等待 1 个进程。您可能希望使用来自Popen 的返回值,并在每个子进程上调用waitcommunicate。然后,您可以另外使用返回值来确保它们都成功死亡:

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

如果一切正常,希望它们都为 0。

【讨论】:

  • communicate() 在这里如果 3 个流都没有重定向到 PIPE 是没用的。 wait() 这里应该够用了...
  • 啊,我想我可能知道现在发生了什么……因为这是一个非阻塞调用,我在任务完成之前看到了“print m”。 ./autogen.sh 可能已排队并仍在处理它。我再等一会儿,看看所有文件夹是否都正常。
  • @glglgl: 在这种情况下,communicate 等同于 wait。尽管如此编辑。
【解决方案2】:

具有虚拟系统调用的类似构建程序按预期工作:

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()

你确定输出真的丢失了,还是只是延迟了?

顺便说一句:

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

更优雅...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-20
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多