为什么要缓冲子进程(重定向到无缓冲文件)的标准输出?

时间:2011-05-07 16:46:04

标签: python subprocess stdout popen buffering

来自http://docs.python.org/library/functions.html#open

  

可选的bufsize参数   指定文件所需的缓冲区   size:0表示无缓冲,1表示行   缓冲,任何其他正值   意味着使用(大约)的缓冲区   那个大小。负面bufsize意味着   使用系统默认值,即   通常为tty设备缓冲线路   并完全缓冲其他文件。如果   省略,使用系统默认值。

我正在传递0作为下面的bufsize而没有使用flush()当我运行main_process时没有输出写入文件。
是什么原因?

# --------------------------------- sub_process.py
import sys
import time

if __name__ == '__main__':
    print 'printed from redirect.py'
    # why is the following flush() needed? 'std-output' is (?) unbuffered...
    sys.stdout.flush() 
    time.sleep(6)


# --------------------------------- main_process.py
import subprocess
import time

if __name__ == '__main__':
    p = subprocess.Popen(
        ['python', 'sub_process.py'],
        stdout=open('std-output', 'w', 0))
    time.sleep(3)
    p.terminate()

2 个答案:

答案 0 :(得分:6)

将python与-u标志一起使用,例如:

if __name__ == '__main__':
    p = subprocess.Popen(
        ['python', '-u', 'sub_process.py'],
        stdout=open('std-output', 'w'))
    time.sleep(3)
    p.terminate()

答案 1 :(得分:5)

扩展Magnus Skog解决方案(顺便提一下:) :):

基本上发生的事情是,当子进程将派生一个新进程时,它将使用os.dup2(查看subprocess.Popen._execute_child)将stdout参数复制到新的子进程stdout(fileno = 1),这将保持无缓冲状态(正如dup2所做的那样),到目前为止一切都很好,但是当python默认启动时(在子进程中)如果python没有看到-u标志,它会将stdout的缓冲区设置为行缓冲区(取查看main python function。),它将覆盖您之前设置的缓冲标志。

希望这更能解释您所看到的行为。