Dav*_*vid 24 python stdin buffering
我正在使用以下bash命令模式运行memcached:
memcached -vv 2>&1 | tee memkeywatch2010098.log 2>&1 | ~/bin/memtracer.py | tee memkeywatchCounts20100908.log
Run Code Online (Sandbox Code Playgroud)
尝试跟踪无与伦比的获取到平台键的集合.
memtracer脚本位于下方并按预期工作,只有一个小问题.看到中间日志文件大小,memtracer.py在memkeywatchYMD.log大小约为15-18K之前不会开始输入.有没有更好的方法来读取stdin或者可能是将缓冲区大小降低到1k以下以获得更快的响应时间?
#!/usr/bin/python
import sys
from collections import defaultdict
if __name__ == "__main__":
keys = defaultdict(int)
GET = 1
SET = 2
CLIENT = 1
SERVER = 2
#if <
for line in sys.stdin:
key = None
components = line.strip().split(" ")
#newConn = components[0][1:3]
direction = CLIENT if components[0].startswith("<") else SERVER
#if lastConn != newConn:
# lastConn = newConn
if direction == CLIENT:
command = SET if components[1] == "set" else GET
key = components[2]
if command == SET:
keys[key] -= 1
elif direction == SERVER:
command = components[1]
if command == "sending":
key = components[3]
keys[key] += 1
if key != None:
print "%s:%s" % ( key, keys[key], )
Run Code Online (Sandbox Code Playgroud)
Ale*_*lli 33
您可以使用python的-u标志从stdin/stdout中完全删除缓冲:
-u : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)
see man page for details on internal buffering relating to '-u'
Run Code Online (Sandbox Code Playgroud)
并且手册页澄清了:
-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 xread-
lines(), 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.
Run Code Online (Sandbox Code Playgroud)
除此之外,不支持更改现有文件的缓冲,但是您可以使用os.fdopen创建具有与现有文件相同的基础文件描述符的新文件对象,并可能使用不同的缓冲.也就是说,
import os
import sys
newin = os.fdopen(sys.stdin.fileno(), 'r', 100)
Run Code Online (Sandbox Code Playgroud)
应该绑定newin到一个文件对象的名称,该文件对象读取与标准输入相同的FD,但一次只缓冲大约100个字节(并且您可以继续sys.stdin = newin使用新文件对象作为此处的标准输入).我说"应该",因为这个区域过去常常在某些平台上出现一些错误和问题(提供完全通用的跨平台功能非常困难) - 我不确定它现在的状态是什么,但是我d绝对建议在所有感兴趣的平台上进行全面测试,以确保一切顺利.(-u,完全删除缓冲,如果可能满足您的要求,应该在所有平台上使用更少的问题).
Sør*_*org 22
你可以简单地使用sys.stdin.readline()而不是sys.stdin.__iter__():
import sys
while True:
line = sys.stdin.readline()
if not line: break # EOF
sys.stdout.write('> ' + line.upper())
Run Code Online (Sandbox Code Playgroud)
这使我在Ubuntu 13.04上使用Python 2.7.4和Python 3.3.1进行行缓冲读取.
Ant*_*ala 11
在sys.stdin.__iter__仍然行缓冲,一个可具有一个其行为大多相同的迭代器(停止在EOF,而stdin.__iter__不会)通过使用的2个参数的形式iter作出的一个迭代sys.stdin.readline:
import sys
for line in iter(sys.stdin.readline, ''):
sys.stdout.write('> ' + line.upper())
Run Code Online (Sandbox Code Playgroud)
或提供None哨兵(但请注意,您需要自己处理EOF条件).
这在 Python 3.4.3 中对我有用:
import os
import sys
unbuffered_stdin = os.fdopen(sys.stdin.fileno(), 'rb', buffering=0)
Run Code Online (Sandbox Code Playgroud)
的文档fdopen()说它只是 的别名open()。
open()有一个可选buffering参数:
buffering是一个可选整数,用于设置缓冲策略。传递 0 来关闭缓冲(仅在二进制模式下允许),传递 1 来选择行缓冲(仅在文本模式下可用),传递一个 > 1 的整数来指示固定大小块缓冲区的大小(以字节为单位)。
换句话说: