И совместно используемая информация

i sovmestno ispolzuemaya informaciya 1 Системные инструменты параллельного выполнения

Теперь, чтобы узнать, как получить код завершения процесса, порожденного ветвлением, напишем простую программу, выполняющую ветвление: сценарий в примере 5.17 порождает дочерние процессы и выводит коды их завершения, возвращаемые функцией os.wait, пока не будет нажата клавиша q”.

Пример 5.17. PP4E\System\Exits\testexit_fork.py

порождает дочерние процессы и получает коды их завершения вызовом функции os.wait; прием ветвления может использоваться в Unix и Cygwin, но он не работает в стандартной версии Python 3.1 для Windows;

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

import os

exitstat = 0

def child(): # здесь можно вызвать os.exit для завершения

global exitstat # изменит глобальную переменную этого процесса

exitstat += 1 # код завершения для функции wait родителя

print(‘Hello from child’, os.getpid(), exitstat) os._exit(exitstat) print(‘never reached’)

def parent():

while True:

newpid = os.fork() # запустить новую копию процесса

if newpid == 0: # если это копия, вызвать функцию child

child() # ждать ввода q с консоли

else:

pid, status = os.wait()

print(‘Parent got’, pid, status, (status >> 8)) if input() == ‘q’: break

if __name__ == ‘__main__’: parent()

Если запустить эту программу в Linux, Unix или Cygwin (не забывайте, что функция fork не работает в стандартной версии Python для Windows, — по крайней мере, когда я работал над четвертым изданием этой книги), она выведет следующие результаты:

[C:\\PP4E\System\Exits]$ python testexit_fork.py

Hello from child 5828 1

Parent got 5828 256 1

Hello from child 9540 1

Parent got 9540 256 1

Hello from child 3152 1

Parent got 3152 256 1 q

Если внимательно изучить этот вывод, можно заметить, что код завершения (последнее выводимое число) всегда одинаков — 1. Поскольку ответвленные процессы начинают жизнь как копии создавших их процессов, они также получают копию глобальной памяти. Поэтому каждый дочерний процесс получает и изменяет собственную глобальную переменную exitstat, не трогая экземпляров этой переменной в других процессах. В то же время дочерние процессы получают копии файловых дескрипторов, которые используются совместно с родительским процессом, и именно поэтому вывод от дочерних процессов попадает в то же самое место.

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

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