Python 并行 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的结果?
附注:如果我以串行方式运行这段代码(也就是用subprocess.call而不是Popen),它就能正常工作。
2 个回答
1
一个结构类似的程序,使用了一个虚拟的系统调用,运行得很正常:
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)):
这样做更优雅...
1
你的代码在我这儿能正常运行,应该可以启动所有的进程。不过你给的信息不太多,我们不知道具体哪里不一样。
在你贴的代码里,没有重定向输出,所以你可能看到的是子进程的 stderr
输出流。不过有一点需要注意:
os.wait()
…这段代码只会等待一个进程。你可能需要使用 Popen
的返回值,然后对每个子进程调用 wait
或 communicate
。这样你还可以使用返回值来确保它们都正常结束:
# Instead of os.wait():
for p in ps:
p.wait()
print 'A process returned:', p.returncode
希望如果一切正常,它们的返回值应该都是 0。