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

Pio*_*ost 9 python subprocess stdout popen buffering

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

可选的bufsize参数指定文件所需的缓冲区大小: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()
Run Code Online (Sandbox Code Playgroud)

ral*_*nja 6

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

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


mou*_*uad 5

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

嗯,基本上什么情况是,当子将一个新的进程会复制标准输出参数使用os.dup2(看看新的子标准输出(的fileno = 1)subprocess.Popen._execute_child),这将保持缓冲状态(因为什么DUP2做),一切到现在为止是好的,但是当Python会默认启动(在子),如果蟒蛇没有看到-u标志将设置标准输出排队缓冲的缓冲(看看在主Python函数.),这将覆盖您之前设置缓冲标志.

希望这更能解释你所看到的行为.