壳管异步工作

时间:2013-05-15 09:22:14

标签: python shell stdout stdin

我认为每个进程管道连接都是异步工作,但事实并非如此。

a.py

#!/usr/bin/env python
import sys
import time
for line in sys.stdin:
    time.sleep(2)
    sys.stdout.write(line.upper())
    sys.stdout.flush()

和b.py

#!/usr/bin/env python
import sys
for line in sys.stdin:
    sys.stdout.write(line.capitalize())
    sys.stdout.flush()

和test.txt

hello
world
python

以下代码逐一显示每行2秒。

$ ./a.py < test.txt
HELLO
WORLD
PYTHON

但是下面的代码完全显示了一次。

$ ./a.py < test.txt | ./b.py
Hello
World
Python

看起来shell管道正在同步工作。我怎么能异步做?

2 个答案:

答案 0 :(得分:0)

你可以使用线程,但我不知道这是否适合你的喜好。 ;)

Ps:python中的线程非常简单,如果需要,我可以提供一个例子。

答案 1 :(得分:0)

代码的问题在于,虽然表达式是......

for line in sys.stdin:
    # ...

...将sys.stdin视为迭代器,在sys.stdin命中EOF之前似乎不会产生任何值,就像sys.stdin.readlines()的行为一样。

对于第一种情况,它几乎立即命中EOF,但在第二种情况下,它必须等待a.py终止,这需要6秒。

你必须像这样重写b.py的代码......

#!/usr/bin/env python
import sys
while 1:
    line = sys.stdin.readline()
    if not line:
        break
    sys.stdout.write(line.capitalize())
    sys.stdout.flush()

...使用readline()一旦有一整行就让调用返回,而不是等待EOF。

如果您想要从文本文件以外的其他方式输入输入,您可能也应对a.py进行类似的更改。