Семейство функций os. spawn

semejstvo funkcij os spawn Системные инструменты параллельного выполнения

Функции os.spawnv и os.spawnve впервые были представлены как инструменты запуска программ в Windows, напоминающие по своему действию комбинацию функций fork/exec в Unix-подобных системах. На сегодняшний день эти функции доступны на обеих платформах, в Windows и в Unix-подобных системах, а кроме того, были добавлены варианты, повторяющие функциональность других членов семейства os.exec.

В последние версии Python был включен переносимый модуль subprocess с целью заменить эти функции. Фактически руководство по библиотеке Python включает примечание, отмечающее, что в составе этого модуля имеются более мощные и эквивалентные инструменты, которым следует отдавать предпочтение перед функциями os.spawn. Кроме того, новейший пакет multiprocessing, в совокупности с функциями os.exec, позволяет добиться тех же результатов переносимым способом, как мы уже видели выше. Тем не менее функции семейства os.spawn по- прежнему доступны и могут встретиться вам в действующих сценариях на языке Python.

Функции из семейства os.spawn запускают программу, указанную в командной строке, в виде нового процесса в Windows и в Unix-подобных системах. По своему действию они напоминают комбинацию функций fork/exec в Unix и могут использоваться как альтернатива функциям system и popen, с которыми мы уже познакомились. В следующем примере выполняется запуск программы на языке Python двумя традиционными способами (во втором случае дополнительно выполняется чтение стандартного потока вывода программы):

C:\\PP4E\System\Processes> python

>>> print(open(‘makewords.py’).read())

print(‘spam’) print(‘eggs’) print(‘ham’)

>>> import os

>>> os.system(‘python makewords.py’)

spam eggs ham 0

>>> result = os.popen(‘python makewords.py’).read()

>>> print(result)

spam eggs ham

Функции, эквивалентные функции os.spawn, имеющие чуть более сложную сигнатуру, что обеспечивает более полный контроль над способом запуска программы, — позволяют получить тот же эффект:

>  >> os.spawnv(os.P_WAIT, rC:\Python31\python’, (‘python’, ‘makewords.py’)) spam eggs ham

0

>  >> os.spawnl(os.P_NOWAIT, r’C:\Python31\python’, ‘python’, ‘makewords.py’) 1820

>  >> spam

eggs ham

Из всех этих способов функция spawn больше всего напоминает прием ветвления программ в Unix. В действительности она не копирует вызывающий процесс (поэтому операции, использующие общие дескрипторы, не работают), но может использоваться для запуска программы Windows, выполняемой совершенно независимо от вызвавшей программы. Сценарий в примере 5.35 делает сходство с шаблонами программирования в Unix еще более очевидным. Он запускает программу с помощью комбинации fork/exec в Unix-подобных системах (включая оболочку Cygwin) или вызывает os.spawnv в Windows.

Пример 5.35. PP4E\System\Processes\spawnv.py

запускает параллельно 10 копий child.py; для запуска программ в Windows использует spawnv (как fork+exec); флаг P_OVERLAY обозначает замену, флаг P_DETACH перенаправляет stdout потомка в никуда; можно также использовать переносимые инструменты из модуля subprocess или из пакета multiprocessing!

import os, sys

for i in range(10):

if sys.platform[:3] == ‘win’:

pypath = sys.executable

os.spawnv(os.P_NOWAIT, pypath, (‘python’, ‘child.py’, str(i))) else:

pid = os.fork()

if pid != 0:

print(‘Process %d spawned’ % pid) else:

os.execlp(‘python’, ‘python’, ‘child.py’, str(i))

print(‘Main process exiting.’)

Чтобы понять, как действуют эти примеры, вам необходимо познакомиться с аргументами, которые передаются функциям spawn. В этом сценарии мы передаем функции os.spawnv флаг режима запуска процесса, полный путь к выполняемому файлу интерпретатора Python и кортеж строк, представляющих команду оболочки, запускающую новую программу. Путь к выполняемому файлу интерпретатора Python доступен сценариям как sys.executable. В общем случае флаг режима запуска процесса может состоять из следующих предопределенных значений:

os.P_NOWAIT и os.P_NOWAITO

Функции spawn возвращают управление сразу после запуска нового процесса и возвращают его числовой идентификатор ID. Доступны в Unix и Windows.

os.P_WAIT

Функции spawn не возвращают управление, пока новый процесс не завершится, и в случае успеха возвращают код его завершения, в противном случае — отрицательный номер сигнала («-signal»), если работа процесса была прервана сигналом. Доступен в Unix и Windows.

os.P_DETACH и os.P_OVERLAY

Флаг P_DETACH похож на флаг P_NOWAIT, но при этом новый процесс отсоединяется от консоли вызывающего процесса. Если был использован флаг P_OVERLAY, текущая программа будет замещена (как при использовании функции os.exec). Доступен в Windows.

Фактически в семействе spawn насчитывается восемь различных функций. Все они выполняют запуск программ, но несколько отличаются сигнатурами. Символ «l» в их именах означает, что аргументы программы передаются в виде списка, символ «p» означает, что поиск выполняемого файла программы будет производиться с учетом системного пути, а символ «e» означает, что функции может быть передан словарь, определяющий окружение порождаемой программы: функция os.spawnve, например, действует так же, как функция os.spawnv, но принимает в дополнительном четвертом аргументе словарь, определяющий иное окружение для порождаемой программы (по умолчанию порождаемые процессы наследуют окружение родительского процесса):

os.spawnl(mode, path, …)

os.spawnle(mode, path, …, env)

os.spawnlp(mode, file, …) # только в Unix

os.spawnlpe(mode, file, …, env) # только в Unix os.spawnv(mode, path, args) os.spawnve(mode, path, args, env)

os.spawnvp(mode, file, args) # только в Unix

os.spawnvpe(mode, file, args, env) # только в Unix

Имена этих функций повторяют имена и сигнатуры функций из семейства os.exec, поэтому дополнительные подробности, касающиеся отличий между их вариантами, вы найдете в описании функций os.exec, выше в этой главе. В отличие от функций os.exec только половина функций os.spawn, не использующих системный путь (то есть без символа «p» в их именах), в настоящее время реализованы в версии Python для Windows. В Windows поддерживаются все флаги режимов запуска процессов, но флаги os.P_DETACH и os.P_OVERLAY недоступны в Unix. Со временем перечисленные особенности могут измениться, поэтому обязательно проверьте их описание в руководстве по библиотеке Python или запустите встроенную функцию dir, передав ей имя модуля os после его импортирования.

Ниже приводится вывод сценария из примера 5.35, запущенного в Windows. Он порождает 10 копий программы child.py, с которой мы встречались выше в этой главе:

C:\\PP4E\System\Processes> type child.py import os, sys print(‘Hello from child’, os.getpid(), sys.argv[1])

C:\\PP4E\System\Processes> python spawnv.py

Hello from child -583587 0

Hello from child -558199 2

Hello from child -586755 1

Hello from child -562171 3

Main process exiting.

Hello from child -581867 6

Hello from child -588651 5

Hello from child -568247 4

Hello from child -563527 7

Hello from child -543163 9

Hello from child -587083 8

Обратите внимание, что эти копии программы выводят свою информацию в случайном порядке, а родительская программа завершается раньше, чем завершатся все дочерние; все эти программы действительно выполняются в Windows параллельно. Обратите также внимание, что вывод дочерней программы появляется в окне консоли, где был запущен сценарий spawnv.py, при использовании флага P_NOWAIT стандартный вывод попадает на родительскую консоль, но отправляется в никуда, если использовать флаг P_DETACH (что не является ошибкой при порождении программ с графическим интерфейсом).

После того как я продемонстрировал эту функцию, следует отметить, что оба модуля, subprocess и multiprocessing, на сегодняшний день предлагают более переносимые альтернативные способы запуска программ с использованием командной строки. Фактически если функции os.spawn не обеспечивают вам какого-то уникального поведения, без которого вы не можете обойтись (например, управление всплывающим окном консоли в Windows), платформозависимые отрезки кода, присутствующие в примере 5.35, можно было бы полностью заменить переносимыми инструментами из пакета multiprocessing, использованными в примере 5.33.

Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011

Каталог сайтов Всего.ру
Оцените статью
Секреты программирования
Добавить комментарий