我有一个用QT/c ++编写的长期服务器程序(比如程序A).程序不是那么稳定所以我决定写一个python脚本,如果它崩溃重启它.问题是程序可能启动失败(如果我给它一个使用中的端口),打印错误,然后只是挂起而不退出,所以我必须监视程序的stdout并在失败的启动时杀死它.
这是我的最终代码(好吧,实际上这没关系,你可以忽略它):
self.subp = subprocess.Popen(
r'.\A.exe -server %d' % portnum,
stdout=subprocess.PIPE, bufsize=1)
for line in iter(self.subp.stdout.readline, ''):
print(line, end='')
Run Code Online (Sandbox Code Playgroud)
但我发现我无法读取子进程的stdout中的任何内容,readline方法只是阻塞那里,如果我杀死A进程,python脚本只是退出而没有任何输出.在开始时,我认为这是一个子进程模块的问题,但经过一些测试,我发现它不是.如果我用其他一些Windows控制台程序替换A.exe命令行,例如ping -t,一切正常.所以我认为这可能是A程序的问题.
幸运的是,我有一个A的源代码,这里是一个处理输出的部分:
printf("Server is starting on port %u\n", Config.ServerPort);
if(server->listen())
printf("Starting successfully\n");
else
printf("Starting failed!\n");
Run Code Online (Sandbox Code Playgroud)
经过一些搜索,我添加fflush(stdout);到这段代码的末尾,重建程序,现在它的工作原理
所以我的问题是我仍然无法理解,原来的A程序代码有什么问题?没有强制刷新,它可以在程序启动后立即在Windows控制台中正确打印这些字符串.为什么在输出管道上使用管道时缓冲输出?我在标准c工具中看到,输出将在换行时自动刷新,但为什么不在我的情况下呢?这是一个Windows问题,还是编译问题?
A程序用QT/C++编译,QT版本是4.7.4(x32),C++编译器是ming32 g ++自带QT(GCC 4.4.0),所有测试都在win7x64平台上进行,我的python版本是2.7.2