在Python中以非阻塞方式收集子流程输出

在Python中以非阻塞方式收集子流程输出,python,subprocess,blocking,Python,Subprocess,Blocking,有没有一种简单的方法可以收集子流程的输出而不必实际等待它 我可以考虑创建一个带有捕获其标准输出的子进程.Popen(),然后调用p.communicate(),但这会一直阻塞,直到子进程终止 我可以考虑使用subprocess.check\u output()或类似的方法,但这也会造成阻塞 我需要一些我可以启动的东西,然后做其他事情,然后检查子进程是否被终止,如果是,则获取其输出 我可以想出两个相当复杂的方法来实现这一点: 将输出重定向到一个文件中,然后在终止后,我可以从该文件中读取输出 实现并

有没有一种简单的方法可以收集子流程的输出而不必实际等待它

我可以考虑创建一个带有捕获其标准输出的
子进程.Popen()
,然后调用
p.communicate()
,但这会一直阻塞,直到子进程终止

我可以考虑使用
subprocess.check\u output()
或类似的方法,但这也会造成阻塞

我需要一些我可以启动的东西,然后做其他事情,然后检查子进程是否被终止,如果是,则获取其输出

我可以想出两个相当复杂的方法来实现这一点:

  • 将输出重定向到一个文件中,然后在终止后,我可以从该文件中读取输出
  • 实现并启动一个处理程序线程(!),该线程不断尝试从子进程的stdout读取数据并将其添加到缓冲区
  • 第一个需要临时文件和磁盘I/O,在我的例子中,我并不喜欢它们。第二种方法意味着要实现相当多的功能


    我想可能有一种更简单的方法我还没有想到,或者在我还没有找到的库中有一个现成的解决方案。

    在线程中调用
    检查输出有什么问题

    import threading,subprocess
    
    output = ""
    
    def f():
        global output
        output = subprocess.check_output("ls")  # ["cmd","/c","dir"] for windows
    
    
    t = threading.Thread(target=f)
    t.start()
    print('Started')
    t.join()
    print(output)
    
    请注意,您可能会尝试使用
    p=subprocess.Popen(cmd,stdout=subprocess.PIPE)
    ,等待
    p.poll()
    成为
    None
    然后尝试读取
    p.stdout
    :这只在输出很小时起作用,否则会出现死锁,因为
    stdout
    缓冲区已满,您必须不时读取它


    使用
    p.stdout.readline()。如果你的应用程序一直打印到输出,那么你可以把它看作是非阻塞的,并且解决方案是可以接受的。

    < P>我想你想要的是一个无缓冲的STDUT流。 这样,您就可以捕获流程的输出,而无需等待它完成。 您可以通过
    subprocess.Popen()
    函数和参数
    stdout=subprocess.PIPE
    实现这一点

    试试这样的

    proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
    
    line = proc.stdout.readline()
    while line:
        print line
        line = proc.stdout.readline()
    

    “线程中的进程”方法没有那么复杂。你需要一个例子吗?我需要并行启动一系列进程。我不知道他们将按什么顺序完成,但我知道他们都在生产。每当一个正在完成,我想收集它的输出,并立即使用它。使用你的线程方法,我需要等待(任何)一堆线程。我想我会用排队的方式。但对我来说,这听起来相当复杂。拥有子进程,并且在主进程中为每个子进程增加一个线程,这听起来像是将结构加倍。我想我更愿意采用临时文件方法。相关:我需要几个并行的临时文件,我不知道哪个会有多快,哪个会在什么时候完成。但我希望在子流程终止后立即使用子流程的输出。