Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 是否为sys.stdin设置较小的缓冲区大小?_Python_Stdin_Buffering - Fatal编程技术网

Python 是否为sys.stdin设置较小的缓冲区大小?

Python 是否为sys.stdin设置较小的缓冲区大小?,python,stdin,buffering,Python,Stdin,Buffering,我使用以下bash命令模式运行memcached: memcached -vv 2>&1 | tee memkeywatch2010098.log 2>&1 | ~/bin/memtracer.py | tee memkeywatchCounts20100908.log 尝试跟踪平台范围内密钥的不匹配获取集 memtracer脚本如下所示,可以根据需要工作,但有一个小问题。查看中间日志文件大小,memtracer.py直到memkeywatchYMD.log才开始获

我使用以下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], )
#/usr/bin/python
导入系统
从集合导入defaultdict
如果名称=“\uuuuu main\uuuuuuuu”:
keys=defaultdict(int)
GET=1
集合=2
客户端=1
服务器=2
#如果<
对于sys.stdin中的行:
键=无
components=line.strip().split(“”)
#newConn=组件[0][1:3]

direction=CLIENT if components[0]。startswith(“您可以使用python的
-u
标志从stdin/stdout中完全删除缓冲:

-u:无缓冲二进制stdout和stderr(也叫pythonunbuffer=x)
有关'-u'的内部缓冲的详细信息,请参见手册页
手册页澄清了:

-u强制标准输入、标准输出和标准输出完全无缓冲。打开
重要的系统还包括stdin、stdout和stderr
二进制模式。请注意,xread中有内部缓冲-
lines()、readlines()和文件对象迭代器(“用于
sys.stdin”),不受此选项的影响。要正常工作
在这方面,您需要在内部使用“sys.stdin.readline()”
一个“while1:”循环。
除此之外,不支持更改现有文件的缓冲区,但您可以使用与现有文件具有相同底层文件描述符的新文件对象,以及可能不同的缓冲区,例如


应该将
newin
绑定到一个文件对象的名称,该文件对象读取与标准输入相同的FD,但一次只能缓冲大约100字节(并且您可以继续使用
sys.stdin=newin
从那时起将新文件对象用作标准输入)“因为这个领域过去在某些平台上有很多bug和问题(要提供完全通用性的跨平台功能是相当困难的)——我不确定它现在的状态,但我绝对建议在所有感兴趣的平台上进行彻底的测试,以确保一切顺利进行。(
-u
,完全删除缓冲,如果可以满足您的要求,那么跨所有平台的问题应该会更少。)

您只需使用
sys.stdin.readline()
而不是
sys.stdin。


这使我能够在Ubuntu 13.04上使用Python 2.7.4和Python 3.3.1进行行缓冲读取。

sys.stdin.\uu iter\uuuu
仍然是行缓冲的,通过使用来生成
sys.stdin.readline的迭代器,可以有一个行为基本相同的迭代器(在EOF时停止,而
stdin.\uu iter\uu\uu不会)

import sys

for line in iter(sys.stdin.readline, ''):
    sys.stdout.write('> ' + line.upper())

或者提供
None
作为哨兵(但请注意,然后您需要自己处理EOF条件)。

这在Python 3.4.3中对我很有效:

import os
import sys

unbuffered_stdin = os.fdopen(sys.stdin.fileno(), 'rb', buffering=0)
上面说它只是
open()
的别名

具有可选的
缓冲
参数:

缓冲是用于设置缓冲策略的可选整数。传递0以关闭缓冲(仅在二进制模式下允许),传递1以选择行缓冲(仅在文本模式下可用),传递大于1的整数以指示固定大小块缓冲区的字节大小

换言之:

  • 完全无缓冲stdin需要二进制模式并将零作为缓冲区大小
  • 行缓冲需要文本模式
  • 任何其他缓冲区大小似乎都可以在二进制和文本模式下工作(根据文档)

我使用python 2.7的唯一方法是:

tty.setcbreak(sys.stdin.fileno())
这将完全禁用缓冲并抑制回音

编辑:关于Alex的回答,第一个命题(使用
-u
调用python)在我的例子中是不可能的(请参阅)


第二个命题(使用较小的缓冲区复制fd:
os.fdopen(sys.stdin.fileno(),'r',100)
)当我使用0或1的缓冲区时,它不起作用,因为它是用于交互式输入的,我需要立即处理按下的每个字符。

可能是您的问题不在于Python,而在于Linux shell在将命令与管道链接时注入的缓冲区。当出现此问题时,输入不是按行缓冲的,而是按行缓冲的t乘以4K块

要停止此缓冲,请在命令链之前使用
expect
包中的
unbuffer
命令,例如:

unbuffer memcached -vv 2>&1 | unbuffer -p tee memkeywatch2010098.log 2>&1 | unbuffer -p ~/bin/memtracer.py | tee memkeywatchCounts20100908.log

<代码> un缓冲器< /C>命令在流水线的中间使用时需要<代码> -p>代码>。谢谢,在Linux环境中的-U标志是胜利者。我以前尝试使用OS.FDOPEN并进入相同的缓冲问题,即使我将缓冲区大小设置为10。不幸的是,Python 3仍然顽固地打开<代码> STDIN 处于缓冲文本模式。现在只有

stdout
stderr
-u
开关的影响。Python3有什么解决方法吗?可能是一个事件驱动库/选项?这在Python3.4.3中对我有效:
os.fdopen(sys.stdin.fileno(),'rb',buffering=0)
@DenilsonSáMaia:不需要自己重新打开它。
sys.stdin
实际上是三层;一个
io.TextIOWrapper
(解码
bytes
str
)包装一个
io.BufferedReader
(缓冲
bytes
)包装一个
io.FileIO
(提交系统调用的实际对象)。它们都可以作为属性使用;
sys.stdin.buffer
使用
tty.setcbreak(sys.stdin.fileno())
unbuffer memcached -vv 2>&1 | unbuffer -p tee memkeywatch2010098.log 2>&1 | unbuffer -p ~/bin/memtracer.py | tee memkeywatchCounts20100908.log