Вопрос подпроцесса Python - PullRequest
4 голосов
/ 10 июля 2009

Я хотел бы иметь возможность порождать процесс в Python и иметь двухстороннюю связь. Конечно, Pexpect делает это, и это действительно мой путь. Тем не менее, это не совсем идеально.

Моя идеальная ситуация состояла бы в том, чтобы иметь кроссплатформенную общую технику, включающую только стандартные библиотеки python. Подпроцесс довольно близок, но тот факт, что мне приходится ждать завершения процесса, прежде чем безопасно взаимодействовать с ним, нежелателен.

Глядя на документацию, он говорит, что есть дескрипторы файлов stdin, stdout и stderr, которыми я могу напрямую манипулировать, но есть большое жирное предупреждение с надписью «Не делай этого». К сожалению, не совсем понятно, почему существует это предупреждение, но из того, что я понял из google, это то, что оно связано с буферизацией os, и можно написать код, который неожиданно блокируется при сбое этих внутренних буферов (как примечание, любые примеры показать неправильный путь и правильный путь будет оценен).

Итак, рискуя моим кодом из-за потенциальных тупиков, я подумал, что было бы интересно использовать опрос или выбрать интерактивное чтение из запущенного процесса, не убивая его. Хотя я теряю (я думаю) кроссплатформенную способность, мне нравится тот факт, что она не требует дополнительных библиотек. Но что еще более важно, я хотел бы знать, является ли это хорошей идеей. Я еще не попробовал этот подход, но я обеспокоен ошибками, которые потенциально могут разрушить мою программу. Это может работать? Что я должен проверить?

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

Ответы [ 4 ]

3 голосов
/ 11 июля 2009

Используйте модуль multiprocessing в стандартной библиотеке Python 2.6.

Он имеет Класс очереди , который может использоваться как для чтения, так и для записи.

1 голос
/ 13 июля 2009

Я делаю это в отдельном потоке, используя очереди сообщений для связи между потоками. В моем случае подпроцесс выводит% complete в стандартный вывод. Я хотел, чтобы основной поток установил симпатичный индикатор выполнения.

 if sys.platform == 'win32':
        self.shell = False
        self.startupinfo = subprocess.STARTUPINFO()
        self.startupinfo.dwFlags = 0x01
        self.startupinfo.wShowWindow = 0
    else:
        self.shell = True
        self.startupinfo = None

. , .

f = subprocess.Popen( cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE, env = env, shell = self.shell, startupinfo = self.startupinfo )
    f.stdin.close()
    line = ''
    while True:
        log.debug('reading')
        c = f.stdout.read(1)

        log.debug(c)

        if len(c) == 0:
            log.info('stdout empty; must be done')
            break;
        if ord(c) == 13:
            continue
        if c == '%':
            # post % complete message to waiting thread.
            line = ''
        else:
            line += c


    log.info('checking for errors')
    errs = f.stderr.readlines()

    if errs:
        prettyErrs = 'Reported Errors: '
        for i in errs:
            prettyErrs += i.rstrip('\n')

        log.warn( prettyErrs )
        #post errors to waiting thread
    else:
        print 'done'        
    return
0 голосов
/ 18 августа 2009

Простите мое невежество по этой теме, но не могли бы вы просто запустить python с флагом -u для «unbuffered»?

Это также может представлять интерес ... http://www.gossamer -threads.com / списки / Python / Python / 658167

0 голосов
/ 10 июля 2009

Короткий ответ: хорошая концепция кроссплатформенной системы для управления процессами не существует, если не внедрить эту концепцию в вашу систему. Это особенно в стандартных библиотеках. Даже различные версии Unix имеют свои собственные проблемы совместимости.

Лучше всего, чтобы инструменты правильно обрабатывали все процессы, чтобы замечать события, которые приходят из любой системы IPC, которая лучше всего работает на любой платформе. Именованные трубы будет общий путь для проблемы, которую вы описываете, но будет реализация различия на каждой платформе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...