stdout консольной программы Windows буферизируется при использовании перенаправления канала - PullRequest
5 голосов
/ 27 января 2012

У меня есть долгосрочная серверная программа (скажем, программа A), написанная на QT / c ++. программа не так стабильна, поэтому я решил написать скрипт на 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='')

но я обнаружил, что ничего не могу прочитать из stdout подпроцесса, метод readline просто блокирует там, и если я убиваю процесс A, скрипт python просто завершается без вывода. в начале я думал, что это проблема модуля подпроцесса, но после некоторого теста я обнаружил, что это не так. если я заменю командную строку A.exe другой консольной программой Windows, например, ping -t, все будет работать правильно. так что я подумал, что это может быть проблемой программы А.

к счастью, у меня есть исходный код 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); в конец этого куска кода, перестраиваем программу, и теперь она работает

так что моя проблема в том, что я до сих пор не могу понять, что не так с оригинальным программным кодом? без принудительного сброса он может правильно распечатать эти строки в консоли Windows сразу после запуска программы. почему вывод буферизируется при использовании pipe на его выходе? я читал, что в стандартном c реализации вывод будет сброшен автоматически на новой строке, но почему бы не в моей ситуации? Это проблема Windows или проблема с компилятором?

Программа A скомпилирована с использованием QT / C ++, версия QT 4.7.4 (x32), компилятором C ++ является ming32 g ++, поставляемый с QT (GCC 4.4.0), все тесты проводились на платформе win7x64, и мой версия Python 2.7.2

...