如何从Python子流程收集输出

如何从Python子流程收集输出,python,subprocess,stanford-nlp,python-multithreading,Python,Subprocess,Stanford Nlp,Python Multithreading,我正在尝试创建一个python进程,该进程读取一些输入,对其进行处理并输出结果。处理由一个子流程(斯坦福大学的NER)完成,为了说明,我将使用“cat”。我不知道NER会给出多少输出,所以我使用运行一个单独的线程来收集所有输出并打印出来。下面的例子说明了这一点 import sys import threading import subprocess # start my subprocess cat = subprocess.Popen( ['cat'], shell=F

我正在尝试创建一个python进程,该进程读取一些输入,对其进行处理并输出结果。处理由一个子流程(斯坦福大学的NER)完成,为了说明,我将使用“cat”。我不知道NER会给出多少输出,所以我使用运行一个单独的线程来收集所有输出并打印出来。下面的例子说明了这一点

import sys
import threading
import subprocess

#   start my subprocess
cat = subprocess.Popen(
    ['cat'],
    shell=False, stdout=subprocess.PIPE, stdin=subprocess.PIPE,
    stderr=None)


def subproc_cat():
    """ Reads the subprocess output and prints out """
    while True:
        line = cat.stdout.readline()
        if not line:
            break
        print("CAT PROC: %s" % line.decode('UTF-8'))

#   a daemon that runs the above function
th = threading.Thread(target=subproc_cat)
th.setDaemon(True)
th.start()

#   the main thread reads from stdin and feeds the subprocess
while True:
    line = sys.stdin.readline()
    print("MAIN PROC: %s" % line)
    if not line:
        break
    cat.stdin.write(bytes(line.strip() + "\n", 'UTF-8'))
    cat.stdin.flush()
当我用键盘输入文本时,这似乎工作得很好。然而,如果我尝试将输入导入我的脚本(cat file.txt | python3 my_script.py),似乎会出现竞速情况。有时我得到正确的输出,有时没有,有时它锁定。任何帮助都将不胜感激


我运行的是Ubuntu 14.04,python 3.4.0。解决方案应该是独立于平台的。

在末尾添加
th.join()
,否则,当主线程退出时,您可能会在线程处理完所有输出之前过早终止线程:守护进程线程在主线程中无法生存(或者删除
th.setDaemon(True)
而不是
th.join()
).

有人曾经告诉我,双管有问题,但没有提供一个好的解决方案。啊,太简单了,我错过了。谢谢D不过,我会将另一个线程保留为守护进程,但我会在主循环之后休眠主线程,以便给另一个线程时间输出结果。@FlorijanStamenkovićtime.sleep()在这里是错误的。如果子进程可能卡住,您可以将
timeout
参数传递给
th.join()
。J.F.,谢谢您的评论。我不知道join()会有什么帮助。原因如下:@FlorijanStamenković
th.join()
在线程完成或超时发生之前不会返回。不像
time.sleep()。我没有完成之前的评论。很抱歉。等待守护进程线程似乎毫无意义的原因是,它是来自单独进程的无限循环轮询输出。这是永远不会完成的。从这个意义上讲,join()和timeout()或sleep()似乎是一回事。最后,我放弃了所有的多线程,编写了一个简单的Java程序来处理Stanford的NER,这样我就可以控制它每输入一行输出一行。在这种情况下,我可以同步Python进程和外部进程,而不需要多线程。