subprocess.Popen и буферизованный вывод процесса - PullRequest
2 голосов
/ 09 февраля 2011

Из кода Python я хочу запустить двоичную программу, которая получает свои параметры из stdin.Используя модуль подпроцесса, это должно быть просто:

import subprocess
command = [ 'my_program' ]
p = subprocess.Popen( command,  \
        stdin = subprocess.PIPE, stdout = subprocess.PIPE, \
        env={ "GFORTRAN_UNBUFFERED_ALL": "1"} )
p.stdin.write ( stdin_stuff )
while True:
  o = p.stdout.readline()
  if p.poll() != None: 
    break
  # Do something with stdout

Теперь, это запускает программу, но скрипт Python просто висит там.Я понимаю, что это вполне может быть связано с тем, что gfortran (который я использую для компиляции my_program, буферизует поток stdout. Gfortran позволяет использовать переменную окружения GFORTRAN_UNBUFFERED_ALL, как я это сделал, а также использовать встроенную переменную FLUSH () в коде fortran)., но все равно не повезло: код python все еще зависает.

Ответы [ 2 ]

4 голосов
/ 09 февраля 2011

Вам больше повезет, если вы используете Popen.communicate() для отправки строк процессу 'stdin, а не для записи в него вручную.

stdoutdata, stderrdata = p.communicate(stdin_stuff)
2 голосов
/ 09 февраля 2011

Чтобы дополнить ответ Aphex , здесь соответствующая часть документации :

Внимание

Используйте communicate() вместо .stdin.write, .stdout.read или .stderr.read, чтобы избежать взаимных блокировок из-за того, что другие буферы конвейера ОС заполняют и блокируют дочерний процесс.

...