当stdin是非交互式时,如何在python中清除stdin缓冲区

时间:2015-03-06 19:53:20

标签: python python-3.x

如何在没有阻塞的情况下从python中的stdin缓冲区读取所有内容?我找到的堆栈溢出解决方案都没有用,因为我的stdin是非交互式的。

我试过了:

tcflush

tcflush(sys.stdin, TCIOFLUSH)不适用于非交互式标准输入。

选择

while select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], []):
  sys.stdin.read(1)

while len(select.select([sys.stdin.fileno()], [], [], 0.0)[0])>0:
  os.read(sys.stdin.fileno(), 4096)

哪个不起作用,因为while头部的条件总是False

还有其他想法吗?

修改

更确切地说:

我的代码应该

  • 如果输入缓冲区为空,则不执行任何操作
  • 如果有缓冲区则清空缓冲区

所以永远不会阻止。

2 个答案:

答案 0 :(得分:1)

您在select()通话中使用零秒超时,这有效地使选择进入一次性轮询操作,等待数据可用。

while len(select.select([sys.stdin.fileno()], [], [], 0.0)[0])>0:
                                                       ^
                                                       |
                                                This means don't wait

尝试改为:

while len(select.select([sys.stdin.fileno()], [], [], None)[0]) > 0:

答案 1 :(得分:0)

感谢您的建议。毕竟,这毕竟是一个奇怪的并发问题。

当我在select通话中设置超时时,它可以正常工作。因此,当我调用select时,似乎缓冲区确实没有被填充。

不起作用(与问题中的相同):

while select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], []):
  sys.stdin.read(1)

工作:

while select.select([sys.stdin], [], [], 0.01) == ([sys.stdin], [], []):
  sys.stdin.read(1)

由于我想要阅读的内容是基于行的,我可以使用input一次读取整行,而不是使用read读取单个字符,然后减慢超时在while循环中不会引人注意。 (缓冲区中最多有5-10行。)

我对此解决方案并不完全满意,因为它涉及等待任意时间(0.01总是足够吗?)。但另一方面,我现在无法想出更好的解决方案,因为我无法影响代码写入"我的标准品#34;。