我正在使用以下bash命令模式运行memcached:
memcached -vv 2>&1 | tee memkeywatch2010098.log 2>&1 | ~/bin/memtracer.py | tee memkeywatchCounts20100908.log
尝试跟踪无与伦比的获取到平台键的集合.
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], )
Alex Martell.. 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'
并且手册页澄清了:
-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.
除此之外,不支持更改现有文件的缓冲,但是您可以使用os.fdopen创建具有与现有文件相同的基础文件描述符的新文件对象,并可能使用不同的缓冲.也就是说,
import os import sys newin = os.fdopen(sys.stdin.fileno(), 'r', 100)
应该绑定newin
到一个文件对象的名称,该文件对象读取与标准输入相同的FD,但一次只缓冲大约100个字节(并且您可以继续sys.stdin = newin
使用新文件对象作为此处的标准输入).我说"应该",因为这个区域过去常常在某些平台上出现一些错误和问题(提供完全通用的跨平台功能非常困难) - 我不确定它现在的状态是什么,但是我d绝对建议在所有感兴趣的平台上进行全面测试,以确保一切顺利.(-u
,完全删除缓冲,如果可能满足您的要求,应该在所有平台上使用更少的问题).
您可以使用python的-u
标志从stdin/stdout中完全删除缓冲:
-u : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)
see man page for details on internal buffering relating to '-u'
并且手册页澄清了:
-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.
除此之外,不支持更改现有文件的缓冲,但是您可以使用os.fdopen创建具有与现有文件相同的基础文件描述符的新文件对象,并可能使用不同的缓冲.也就是说,
import os import sys newin = os.fdopen(sys.stdin.fileno(), 'r', 100)
应该绑定newin
到一个文件对象的名称,该文件对象读取与标准输入相同的FD,但一次只缓冲大约100个字节(并且您可以继续sys.stdin = newin
使用新文件对象作为此处的标准输入).我说"应该",因为这个区域过去常常在某些平台上出现一些错误和问题(提供完全通用的跨平台功能非常困难) - 我不确定它现在的状态是什么,但是我d绝对建议在所有感兴趣的平台上进行全面测试,以确保一切顺利.(-u
,完全删除缓冲,如果可能满足您的要求,应该在所有平台上使用更少的问题).
你可以简单地使用sys.stdin.readline()
而不是sys.stdin.__iter__()
:
import sys while True: line = sys.stdin.readline() if not line: break # EOF sys.stdout.write('> ' + line.upper())
这使我在Ubuntu 13.04上使用Python 2.7.4和Python 3.3.1进行行缓冲读取.
在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())
或提供None
哨兵(但请注意,您需要自己处理EOF条件).