6

我有一个用 QT/c++ 编写的长期运行的服务器程序(比如程序 A)。该程序不是那么稳定,所以我决定编写一个 python 脚本以在它崩溃时重新启动它。问题是程序可能启动失败(如果我给它一个正在使用的端口),打印错误然后就挂在那里而不退出,所以我必须监视程序的标准输出并在启动失败时将其终止。

这是我最终代码的一部分(其实这没关系,你可以忽略它):

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='')

但我发现我无法从子进程的标准输出中读取任何内容,readline 方法只是阻塞在那里,如果我杀死 A 进程,python 脚本就会退出而没有任何输出。一开始,我以为是子进程模块的问题,但经过一番测试,我发现不是。如果我用其他一些 Windows 控制台程序(例如 ping -t)替换 A.exe 命令行,则一切正常。所以我认为这可能是A程序的问题。

幸运的是,我有 A 的源代码,这里有一段处理输出:

printf("Server is starting on port %u\n", Config.ServerPort);

if(server->listen())
    printf("Starting successfully\n");
else
    printf("Starting failed!\n");

经过一番搜索,我添加fflush(stdout);到这段代码的末尾,重建程序,现在它可以工作了

所以我的问题是我还是看不懂,原来的A程序代码有什么问题?在没有强制刷新的情况下,它可以在程序启动后立即在 Windows 控制台中正确打印这些字符串。为什么在输出上使用管道时输出会被缓冲?我读到在标准 c 实现中,输出将在换行符上自动刷新,但在我的情况下为什么不呢?这是windows问题还是编译器问题?

A程序是用QT/C++编译的,QT版本是4.7.4(x32),C++编译器是QT自带的ming32 g++(GCC 4.4.0),所有测试都是在win7x64平台上做的,我的python版本是2.7.2

4

0 回答 0