您的位置:首页 > 编程语言 > Python开发

后台运行python程序输出缓冲区问题

2016-06-13 16:00 656 查看

后台运行python程序输出缓冲区问题

问题发现

写脚本给工具使用时,遇到一个问题:用python写的脚本输出的内容没有实时显示在发版工具的输出上,而是等脚本执行完后一次性输出。一开始以为是工具的问题,找了半天也没找到什么问题,最后发现后台运行python程序输出到缓冲区的问题,这里总结一下。

问题描述

为了验证这个问题,写了一个测试脚本,从0到19每秒钟输出一个数字:

vim test.py
#!/usr/local/bin/python
#-*- coding: utf-8 -*-

import sys,time

for x in xrange(0,20):
print x
time.sleep(1)


在命令行下用以下命令直接执行该脚本没有问题:

python test.py


而用以下命令后台执行该脚本时,发现生成了日志文件,但是并没有每秒输出,而是在脚本执行完毕之后一次性输出所有数字:

python test.py > test.log &


从而验证了后台运行python程序输出会先输出到缓冲区,等缓冲区满或者脚本结束后再输出。

网上看到stderr输出是无缓存的,于是再写一个脚本验证该问题:

vim test1.py
#!/usr/local/bin/python
#-*- coding: utf-8 -*-

import sys

sys.stdout.write("stdout1 ")
sys.stderr.write("stderr1 ")
sys.stdout.write("stdout2 ")
sys.stderr.write("stderr2 ")


运行程序后,输出结果如下:

# python test1.py
stderr1 stderr2 stdout1 stdout2


可以看到stderr的输出都在stdout前面,证明了stderr输出是没有输出到缓冲区的,而stdout有。

通过上面两个实验可得出下面的结论

在linux上后台运行python程序stdout会先输出到缓冲区,等缓冲区满或者脚本结束再输出,而stderr不会先输出到缓冲区。

解决办法

1、运行时加-u参数,如
# python -u test.py


用man查看python的-u参数,说明如下:

Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode. Note that there is internal buffering in xreadlines(), readlines() and file-object iterators (“for line in sys.stdin”) which is not influenced by this option. To work around this, you will want to use “sys.stdin.readline()” inside a “while 1:” loop.

强制stdin,stdout和stderr完全不缓冲。

2、在不要缓冲的每一次print后面添加sys.stdout.flush()函数

3、脚本头部添加-u,如
#!/usr/local/bin/python -u
,道理同方法1

4、添加环境变量
PYTHONUNBUFFERED=1


参考资料

http://www.jb51.net/article/50508.htm

http://blog.csdn.net/joeblackzqq/article/details/7220009
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python 缓冲