Python 有没有办法区分Popen.poll()中的未完成和阻止
我想“播种”一些过程,然后在完成后“收获”它们。使用Python 有没有办法区分Popen.poll()中的未完成和阻止,python,subprocess,Python,Subprocess,我想“播种”一些过程,然后在完成后“收获”它们。使用子流程模块,我在subrun.py中有以下代码: import time, subprocess, shlex, os ok = subprocess.Popen(shlex.split("python ok.py"), stdout=subprocess.PIPE, stderr=open(os.devnull, 'w')) nok = subpro
子流程
模块,我在subrun.py
中有以下代码:
import time, subprocess, shlex, os
ok = subprocess.Popen(shlex.split("python ok.py"),
stdout=subprocess.PIPE,
stderr=open(os.devnull, 'w'))
nok = subprocess.Popen(shlex.split("python nok.py"),
stdout=subprocess.PIPE,
stderr=open(os.devnull, 'w'))
procs = {'ok': ok, 'nok': nok}
while procs:
running = procs.keys()
print "running:", running
for k in running:
proc = procs[k]
rc = proc.poll()
if rc is None:
pass # still running
else:
del procs[k]
print proc.stdout.read()
time.sleep(.4)
ok.py
如下
import sys
print "OK"
sys.exit(0)
并且nok.py
import sys
print "NOK" * 5000
sys.exit(0)
输出是
(dev) C:\work\dev\test>python subrun.py
running: ['ok', 'nok']
running: ['ok', 'nok']
OK
running: ['nok']
running: ['nok']
running: ['nok']
running: ['nok']
running: ['nok']
running: ['nok']
running: ['nok']
Traceback (most recent call last):
File "subrun.py", line 27, in <module>
time.sleep(.4)
(dev)C:\work\dev\test>python subrun.py
正在运行:['ok','nok']
正在运行:['ok','nok']
好啊
正在运行:['nok']
正在运行:['nok']
正在运行:['nok']
正在运行:['nok']
正在运行:['nok']
正在运行:['nok']
正在运行:['nok']
回溯(最近一次呼叫最后一次):
文件“subrun.py”,第27行,在
时间。睡眠(.4)
当子进程在IO上被阻止时,即Popen.poll()
返回None
我可能会为每个进程启动一个线程,它将调用.communicate()[0]
,但这似乎需要很多额外的簿记
有什么方法可以让它工作吗?如果您设置了
stdout=PIPE
,那么您应该读取管道,否则如果子进程生成足够的输出,它可能会永远阻塞
这是代码中的一个bug。修好它
要在子流程完成后获取所有输出,请执行以下操作:
#!/usr/bin/env python
import shlex
from multiprocessing.dummy import Pool
from subprocess import check_output
cmds = map(shlex.split, ["python ok.py", "python nok.py"])
outputs = Pool(len(cmds)).map(check_output, cmds)
如果没有可以阅读的内容,我如何在不堵塞的情况下阅读管道?(subprocess文档对这个主题有点轻描淡写…)我猜您指的是您的答案(?),但这不就是为每个进程启动一个线程,然后读取每个线程块吗?i、 它不是真正的非阻塞读取。是否不可能对子流程中挂起的输出执行真正的非阻塞检查?如果您不喜欢
q.get_nowait()
(这不会阻塞(真的)),那么请阅读使用select、fcntl、iocp等的其余答案。我对该流程不感兴趣,直到它完成,然后我想立即获得它的所有输出,所以这看起来就像是为一些概念上更简单的东西做了大量的簿记…;-)