【问题标题】:Shell pipe working asynchronously壳管异步工作
【发布时间】:2013-05-15 09:22:13
【问题描述】:

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

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 pipe 正在同步工作。我怎样才能异步进行?

【问题讨论】:

    标签: python shell stdout stdin


    【解决方案1】:

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

    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 进行类似的更改。

    【讨论】:

    • 感谢您的回答。我在stackoverflow.com/a/7608205/395425中发现了类似的线程在python2.7中“for”语句正在等待EOF,但python3.3不等待。
    • 后来发现,python 2.x "for line in sys.stdin" 不等到EOF。它似乎正在缓冲。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      • 2019-07-30
      相关资源
      最近更新 更多