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等的其余答案。我对该流程不感兴趣,直到它完成,然后我想立即获得它的所有输出,所以这看起来就像是为一些概念上更简单的东西做了大量的簿记…;-)