Spec-Zone.ru › Python 2.7

popen2 — Подпроцессы с доступными потоками ввода/вывода

Устарело начиная с версии 2.6: Этот модуль устарел. Используйте модуль subprocess. Обратите особое внимание на раздел Замена устаревших функций модулем subprocess.

Этот модуль позволяет запускать процессы и подключаться к их каналам ввода/вывода/ошибок, а также получать их коды возврата под Unix и Windows.

Модуль subprocess предоставляет более мощные возможности для запуска новых процессов и получения их результатов. Использование модуля subprocess предпочтительнее использования модуля popen2.

Основной интерфейс этого модуля представлен тройкой функций-фабрик. Для каждой из них, если указан параметр bufsize, он задаёт размер буфера для каналов ввода/вывода. Параметр mode, если он указан, должен быть строкой 'b' или 't'; в Windows он необходим для определения того, должны ли файлы открываться в двоичном или текстовом режиме. Значение по умолчанию для mode равно 't'.

В Unix, cmd может быть последовательностью, в этом случае аргументы будут переданы непосредственно программе без вмешательства оболочки (как в os.spawnv()). Если cmd является строкой, она будет передана оболочке (как в os.system()).

Единственный способ получить коды возврата для дочерних процессов — использование методов poll() или wait() для классов Popen3 и Popen4; эти методы доступны только в Unix. Эта информация недоступна при использовании функций popen2(), popen3() и popen4(), или эквивалентных функций модуля os. (Обратите внимание, что кортежи, возвращаемые функциями модуля os, имеют другой порядок, чем кортежи, возвращаемые модулем popen2.)

popen2.popen2(cmd[, bufsize[, mode]])

Выполняет cmd как подпроцесс. Возвращает объекты файлов (child_stdout, child_stdin).

popen2.popen3(cmd[, bufsize[, mode]])

Выполняет cmd как подпроцесс. Возвращает объекты файлов (child_stdout, child_stdin, child_stderr).

popen2.popen4(cmd[, bufsize[, mode]])

Выполняет cmd как подпроцесс. Возвращает объекты файлов (child_stdout_and_stderr, child_stdin).

Введено в версии 2.0.

В Unix также доступен класс, определяющий объекты, возвращаемые функциями-фабриками. Они не используются в реализации для Windows и недоступны на этой платформе.

class popen2.Popen3(cmd[, capturestderr[, bufsize]])

Этот класс представляет дочерний процесс. Обычно экземпляры Popen3 создаются с помощью функций-фабрик popen2() и popen3(), описанных выше.

Если вы не используете одну из вспомогательных функций для создания объектов Popen3, параметр cmd представляет собой командную строку оболочки для выполнения в подпроцессе. Флаг capturestderr, если он имеет значение true, указывает, что объект должен захватывать стандартный вывод ошибок дочернего процесса. По умолчанию значение false. Если указан параметр bufsize, он задаёт размер буферов ввода/вывода для обмена с дочерним процессом.

class popen2.Popen4(cmd[, bufsize])

Аналогично Popen3, но всегда захватывает стандартный вывод ошибок в тот же объект файла, что и стандартный вывод. Они обычно создаются с помощью popen4().

Введено в версии 2.0.

1. Объекты Popen3 и Popen4

Экземпляры классов Popen3 и Popen4 имеют следующие методы:

Popen3.poll()

Возвращает -1, если дочерний процесс ещё не завершен, или его код состояния (см. wait()), в противном случае.

Popen3.wait()

Ожидает и возвращает код состояния дочернего процесса. Код состояния кодирует как код возврата процесса, так и информацию о том, завершился ли он с помощью системного вызова exit() или завершился из-за сигнала. Функции для интерпретации кода состояния определены в модуле os; см. раздел Управление процессами для семейства функций W*().

Также доступны следующие атрибуты:

Popen3.fromchild

Объект файла, который предоставляет вывод дочернего процесса. Для экземпляров Popen4 он будет предоставлять как стандартный вывод, так и стандартный поток ошибок.

Popen3.tochild

Объект файла, который предоставляет ввод дочернему процессу.

Popen3.childerr

Объект файла, который предоставляет вывод ошибок дочернего процесса, если для конструктора был указан capturestderr со значением true, иначе None. Этот атрибут всегда равен None для экземпляров Popen4.

Popen3.pid

Идентификатор процесса дочернего процесса.

2. Проблемы управления потоком

Всякий раз, когда вы работаете с любым видом межпроцессного взаимодействия, необходимо тщательно продумать управление потоком. Это также относится к объектам файлов, предоставляемым этим модулем (или эквивалентам модуля os).

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

Существует несколько способов решения этой ситуации.

Простейшим изменением в приложении во многих случаях будет следование этой модели в родительском процессе:

import popen2

r, w, e = popen2.popen3('python slave.py')
e.readlines()
r.readlines()
r.close()
e.close()
w.close()

с кодом такого типа в дочернем процессе:

import os
import sys

# note that each of these print statements
# writes a single long string

print >>sys.stderr, 400 * 'this is a test\n'
os.close(sys.stderr.fileno())
print >>sys.stdout, 400 * 'this is another test\n'

В частности, обратите внимание, что sys.stderr должен быть закрыт после записи всех данных, иначе readlines() не вернётся. Также обратите внимание, что необходимо использовать os.close(), так как sys.stderr.close() не закроет stderr (в противном случае присваивание sys.stderr будет молча закрывать его, поэтому дальнейшие ошибки не будут выведены).

Приложения, которым требуется более общее решение, должны интегрировать ввод/вывод по каналам с их циклами select() или использовать отдельные потоки для чтения каждого из индивидуальных файлов, предоставляемых той или иной функцией popen*() или классом Popen*.

См. также

Module subprocess

Модуль для запуска и управления подпроцессами.

© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/2.7/library/popen2.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API