我一直在阅读this question,and this one,并指出那里提出的解决方案没有达到我要尝试的目的。这个想法类似于this question,但在这里我给出一个更好的例子。
我需要在Python 3.7中构建一个GUI,以监视和控制用C编写的旧软件的执行。现在,我试图简单地从Python调用测试可执行文件并将其打印在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)!
显然,可执行文件的输出仅在执行完成时打印。这意味着,如果旧版可执行文件正在运行,则只有完成后才会显示任何内容。
编辑:我对此没有严格的实时限制,如果打印实际上需要几分钟,那很好,问题是,如果一个流程需要运行几天,那么每隔几天小时(最好是几分钟),需要使用可执行文件中的控制台打印来更新GUI。
答案 0 :(得分:4)
考虑阅读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程序以在打印后刷新stdout,缓冲的stdout似乎是问题的根本原因:
printf("Hello #%d \n",ii);
fflush(stdout);