为什么子进程的标准输出(重定向到无缓冲文件)被缓冲?
来自 http://docs.python.org/library/functions.html#open
可选的 bufsize 参数 指定文件所需的缓冲区 size:0表示无缓冲,1表示行 缓冲,任何其他正值 意味着使用(大约)的缓冲区 那个尺寸。负的 bufsize 意味着 使用系统默认值,即 通常为 tty 设备进行行缓冲 并为其他文件完全缓冲。如果 省略,使用系统默认。
我在下面传递 0 作为 bufsize,但没有使用lush(),当我运行 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()
From http://docs.python.org/library/functions.html#open
The optional bufsize argument
specifies the file’s desired buffer
size: 0 means unbuffered, 1 means line
buffered, any other positive value
means use a buffer of (approximately)
that size. A negative bufsize means to
use the system default, which is
usually line buffered for tty devices
and fully buffered for other files. If
omitted, the system default is used.
I'm passing 0 as bufsize below yet without using flush() there's no output written to the file when I run main_process.
What's the reason?
# --------------------------------- 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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用带有 -u 标志的 python,例如:
Use python with the -u flag, e.g.:
扩展 Magnus Skog 解决方案(顺便说一下 +1 :) ):
基本上,当子进程分叉一个新进程时,它会使用 os.dup2 将 stdout 参数复制到新的子进程 stdout (fileno = 1) (看看subprocess.Popen._execute_child),这将保持无缓冲状态(就像dup2 做的),到目前为止一切都很好,但是当默认情况下启动 python 时(在子进程中),如果 python 没有看到 -u 标志,它将把 stdout 的缓冲区设置为行缓冲区(看看 < a href="http://hg.python.org/cpython/file/bcf04ced5ef1/Modules/main.c#l454">main python function.)这将覆盖您之前设置的缓冲标志。
希望这能更多地解释您所看到的行为。
Extending Magnus Skog solution (+1 by the way :) ):
Well basically what happen is that when subprocess will fork a new process it will duplicate the stdout argument to the new subprocess stdout (fileno = 1) using os.dup2 (look at subprocess.Popen._execute_child) and this will keep the unbuffered state (as what dup2 do), everything until now is good, but when python will be launched (in the subprocess) by default if python don't see the -u flag it will set the buffer of stdout to line buffer (take a look at the main python function.) which will override the buffering flag that you set before.
Hope this explain more the behavior that you was seeing.