Python select()行为很奇怪 [英] Python select() behavior is strange

查看:298
本文介绍了Python select()行为很奇怪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在理解select.select的行为时遇到了一些麻烦。请考虑以下Python程序:

I'm having some trouble understanding the behavior of select.select. Please consider the following Python program:

def str_to_hex(s):
    def dig(n):
        if n > 9:
            return chr(65-10+n)
        else:
            return chr(48+n)
    r = ''
    while len(s) > 0:
        c = s[0]
        s = s[1:]
        a = ord(c) / 16
        b = ord(c) % 16
        r = r + dig(a) + dig(b)
    return r

while True:
    ans,_,_ = select.select([sys.stdin],[],[])
    print ans
    s = ans[0].read(1)
    if len(s) == 0: break
    print str_to_hex(s)

我已将其保存到文件test.py。如果按如下方式调用它:

I have saved this to a file "test.py". If invoke it as follows:

echo 'hello' | ./test.py

然后我得到预期的行为:select never块,所有数据都是印刷;程序然后终止。

then I get the expected behavior: select never blocks and all of the data is printed; the program then terminates.

但如果我以交互方式运行程序,我会得到一个最不受欢迎的行为。请考虑以下控制台会话:

But if I run the program interactively, I get a most undesirable behavior. Please consider the following console session:

$ ./test.py
hello
[<open file '<stdin>', mode 'r' at 0xb742f020>]
68

程序然后挂在那里; select.select现在再次阻止。直到我提供更多输入或关闭输入流才会打印下一个字符(以及所有其余字符),即使已经有字符在等待!任何人都可以向我解释这种行为吗?我在一个我编写的流隧道程序中看到类似的东西并且它破坏了整个事件。

The program then hangs there; select.select is now blocking again. It is not until I provide more input or close the input stream that the next character (and all of the rest of them) are printed, even though there are already characters waiting! Can anyone explain this behavior to me? I am seeing something similar in a stream tunneling program I have written and it's wrecking the entire affair.

感谢阅读!

推荐答案

sys.stdin 读方法>工作在一个比选择更高的抽象级别。当你执行 ans [0] .read(1)时,python实际上从操作系统读取更多的字节并在内部缓冲它们。 select 不知道这个额外的缓冲;它只会看到所有内容都已被读取,因此会阻止,直到EOF或更多输入到达。您可以通过运行类似 strace -e read,选择python yourprogram.py 来观察此行为。

The read method of sys.stdin works at a higher level of abstraction than select. When you do ans[0].read(1), python actually reads a larger number of bytes from the operating system and buffers them internally. select is not aware of this extra buffering; It only sees that everything has been read, and so will block until either an EOF or more input arrives. You can observe this behaviour by running something like strace -e read,select python yourprogram.py.

一个解决方案是用 os.read(ans [0] .fileno(),1) ans [0] .read(1) C $ C>。 os.read 是一个较低级别的界面,它与操作系统之间没有任何缓冲,因此它更适合选择

One solution is to replace ans[0].read(1) with os.read(ans[0].fileno(), 1). os.read is a lower level interface without any buffering between it and the operating system, so it's a better match for select.

或者,使用 -u python >命令行选项似乎也禁用了额外的缓冲。

Alternatively, running python with the -u commandline option also seems to disable the extra buffering.

这篇关于Python select()行为很奇怪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆