Python 实时更新可执行子进程控制台输出

Real Time updating executable subprocess console output in Python

我一直在阅读 this question, and this one and noted that the solutions proposed there did not do the trick I'm trying to pull off. The idea is similar to this question 但我在这里给出了一个更好的例子。

我需要在 Python 3.7 中构建一个 GUI 来监视和控制用 C 编写的遗留软件的执行。现在,我正在尝试简单地从 [=36= 调用测试可执行文件] 并将其打印在 GUI 上,但现在在与 python 相同的控制台上打印就足够了。问题是可执行文件需要很长时间才能完全执行,但同时会打印控制台消息,我需要我的 GUI 及时读取这些消息。

这是一个工作示例:

在 Python 3.7:

import sys
from threading import Thread
import time
import subprocess

class HandleTarget(Thread):
    def __init__(self):
        Thread.__init__(self)

    def run(self):
        subprocess.Popen(["hello.exe"], stdout=sys.stdout, bufsize=1)

class Printer(Thread):
    def __init__(self):
        Thread.__init__(self)

    def run(self):
        for i in range(1, 15):
            sys.stdout.write("Hi back ("+str(i)+")!\n")
            time.sleep(1.0)

thread_1 = HandleTarget()
thread_2 = Printer()

# Launching threads:
thread_1.start()
thread_2.start()

现在,示例可执行文件 ("hello.exe") 可以像这样用 C 构建:

#include <stdio.h>
#include <time.h>

int main() {
    struct timespec time;
    double tic = 0;
    double toc = 0;

    for( int ii = 0; ii < 3 ; ii++){
        clock_gettime(CLOCK_MONOTONIC, &time);
        tic = time.tv_sec;
        toc = tic;

        while(toc-tic<3) {
        clock_gettime(CLOCK_MONOTONIC, &time);
        toc    = time.tv_sec;
        }
        printf("Hello #%d \n",ii);
    }
    return(0); 
}

理想情况下,我需要交错消息 "Hello" 和 "Hi back"。但是如果我 运行 上面的 python 脚本,我得到:

Hi back (1)!
Hi back (2)!
Hi back (3)!
Hi back (4)!
Hi back (5)!
Hi back (6)!
Hi back (7)!
Hi back (8)!
Hi back (9)!
Hello #0 
Hello #1 
Hello #2 
Hi back (10)!
Hi back (11)!
Hi back (12)!
Hi back (13)!
Hi back (14)!

显然,可执行文件的输出仅在执行完成时打印。这意味着如果遗留可执行文件是 运行ning,则只有在完成后才会显示任何内容。

编辑: 我对此没有严格的实时限制,如果打印实际上需要几分钟,那很好,问题是如果一个过程需要 运行 几天,然后每隔几个小时(最好是几分钟),GUI 需要使用可执行文件的控制台打印进行更新。

考虑阅读 Popen.stdout

https://docs.python.org/3/library/subprocess.html?highlight=subprocess#subprocess.Popen.stdout

这是更新程序的输出:

$ python test.py
Hi back (1)!
Hi back (2)!
Hi back (3)!
Hello #0
Hi back (4)!
Hi back (5)!
Hi back (6)!
Hello #1
Hi back (7)!
Hi back (8)!
Hi back (9)!
Hello #2
Hi back (10)!
Hi back (11)!
Hi back (12)!
Hi back (13)!
Hi back (14)!

更新程序:

import sys
from threading import Thread
import time
import subprocess

class HandleTarget(Thread):
    def __init__(self):
        Thread.__init__(self)

    def run(self):
        proc = subprocess.Popen(["hello.exe"], stdout=subprocess.PIPE)
        for line in proc.stdout:
            print(line.strip().decode('utf-8'))


class Printer(Thread):
    def __init__(self):
        Thread.__init__(self)

    def run(self):
        for i in range(1, 15):
            sys.stdout.write("Hi back ("+str(i)+")!\n")
            time.sleep(1.0)

thread_1 = HandleTarget()
thread_2 = Printer()

# Launching threads:
thread_1.start()
thread_2.start()

编辑:

我也修改了C程序打印后刷新标准输出,缓冲标准输出似乎是问题的根本原因:

    printf("Hello #%d \n",ii);
    fflush(stdout);