Подключение к подпроцессу stdin к каналу - PullRequest
3 голосов
/ 07 июня 2011

У меня есть метод, который создает подпроцесс и подключает его STDIN к анонимному каналу; который не работает. Не вызывая никаких исключений, подпроцесс просто никогда не читает данные. (подпроцесс - это исполняемый файл zenity для отображения индикатора выполнения в графическом интерфейсе)

class Screen(object):
    def __init__(self, display = ":0", bin = '/usr/bin/zenity'):
        self.bin = bin
        os.environ['DISPLAY'] = display
        self.dis = display

    def displayProgress(self, text, pulse = True, title = 'Progess'):
    '''Method to represent the 'zenity --progress' command
    '''
        readp, writep = os.pipe()
        reade, writee = os.pipe()

        rfd = os.fdopen(readp, 'r')
        wfd = os.fdopen(writep, 'w')


        if pulse:
            zenhandle = Popen([self.bin, '--progress',
                                         '--title=%s' % title,
                                         '--auto-close',
                                         '--pulsate'],
                              stdin = rfd)
        else:
            zenhandle = Popen([self.bin, '--progress',
                                         '--title=%s' % title,
                                         '--auto-close'],
                              stdin = rfd)

        self.progress = wfd

Идея вызова метода будет неблокирующей, и я могу write() до Screen.progress и записать в STDIN дочернего (zenity) процесса. (zenity рисует гистограмму завершения, считывая значения из STDIN)

Окно отображается на экране, но Screen.progress.write('50') никогда не обновляет панель.

Что я делаю не так?

Изменить:

Если запустить в интерактивном режиме, как только я выйду из оболочки Python, панель начнет двигаться. (пульсирует) Это означает, что он читает что-то только после выхода из процесса python.

Ответы [ 2 ]

1 голос
/ 07 июня 2011

os.fdopen() должен иметь размер буфера 0. Используйте rfd = os.fdopen(readp, 'r', 0).

1 голос
/ 07 июня 2011

Возможно, вам нужно очистить файловые буферы. Попробуйте делать self.progress.flush() после каждой записи.

...