关于Python的subprocess.Popen()对象的问题 (请假设为stdout / stderr生成的字节数不会填满OS管道缓冲区并创建死锁等待OS管道缓冲区接受更多数据的情况)
1)p.stdout.read()和p.wait()的顺序是否重要?
2)在进程终止之前,stdout / stderr subprocess.PIPE块上是否有read()?
3)即使在进程终止后,stdout / stderr subprocess.PIPE文件对象和数据是否可用?
import subprocess
process = subprocess.Popen(args="ls", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
stdout = process.stdout.read()
# Does the above read() block until the process has terminated?
stderr = process.stderr.read()
return_code = process.wait()
process = subprocess.Popen(args="ls", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
return_code = process.wait()
# Are stdout and stderr pipes available now, even after the process terminated?
stdout = process.stdout.read()
stderr = process.stderr.read()
答案 0 :(得分:4)
问:p.stdout.read()和p.wait()的顺序是否重要?
答:没有。
问:在进程终止之前,stdout / stderr subprocess.PIPE上是否有read()? 答:如果没有指定要读取的字节数限制,那么它将阻塞直到流关闭(这可能是进程终止时)。
问:即使进程终止,stdout / stderr subprocess.PIPE文件对象和数据是否可用?
答:是的。
您可能需要特别注意subprocess
文档中的此警告:
警告:当使用
stdout=PIPE
和/或stderr=PIPE
时,这将导致死锁,并且子进程会为管道生成足够的输出,以阻止等待OS管道缓冲区接受更多数据。使用communicate()
来避免这种情况。
答案 1 :(得分:0)
您可能需要考虑使用像sarge
这样的库,它允许在使用子进程执行I / O时具有灵活性。 (披露:我是维护者。我写这部分是为了回应你遇到的那种困难。)