Очереди и подклассы

ocheredi i podklassy Системные инструменты параллельного выполнения

Наконец, помимо простых инструментов запуска и взаимодействия с дочерними процессами, пакет multiprocessing дополнительно:

     Позволяет создавать подклассы класса Process, обеспечивающего базовую структуру процесса и сохранение информации (так же, как threading.Thread, но для процессов).

     Реализует объект Queue, который может совместно использоваться любым количеством процессов для удовлетворения более широких потребностей при обмене данными (так же, как queue.Queue, но для процессов).

Очереди поддерживают более гибкую модель клиент/сервер. Так, сценарий в примере 5.32 порождает три процесса производителя, отправляющие данные в совместно используемую очередь, и периодически проверяет ее на предмет появления результатов — очень похоже на то, как графический интерфейс собирает результаты параллельных вычислений и выводит их, однако здесь параллельные операции выполняются не потоками, а процессами.

Пример 5.32. PP4E\System\Processes\multi4.py

От класса Process можно породить подкласс, так же, как от класса threading. Thread;

объект Queue действует подобно queue.Queue, но обеспечивает обмен данными между процессами, а не между потоками выполнения

import os, time, queue

from multiprocessing import Process, Queue # общая очередь для процессов # очередь — это канал + # блокировки/семафоры

class Counter(Process):

label = ‘ @’

def __init__(self, start, queue): # сохраняет данные для

self.state = start # использования в методе run

self.post = queue Process.__init__(self)

def run(self): # вызывается в новом процессе

for i in range(3): # методом start()

time.sleep(1)

self.state += 1

print(self.label ,self.pid, self.state) # self.pid pid потомка self.post.put([self.pid, self.state]) # stdout совместно

# используется всеми print(self.label, self.pid, ‘-’)

if __name__ == ‘__main__’:

print(‘start’, os.getpid()) expected = 9

post = Queue()

p = Counter(0, post) # запустить 3 процесса, использующих общую очередь

q = Counter(100, post) # потомки являются производителями

r = Counter(1000, post)

p.start(); q.start(); r.start()

while expected: # родитель потребляет данные из очереди

time.sleep(0.5) # очень напоминает графический интерфейс, try: # хотя в ГИ часто используются потоки

data = post.get(block=False)

except queue.Empty:

print(‘no data…’)

else:

print(‘posted:’, data) expected -= 1

p.join(); q.join(); r.join() # дождаться завершения дочерних процессов print(‘finish’, os.getpid(), r.exitcode) # exitcode код завершения

# потомка

Обратите внимание, что в этом сценарии:

     Функция time.sleep имитирует выполнение длительных операций в процессах-производителях.

     Все четыре процесса совместно используют один и тот же поток вывода — функции print выводят текст в одно и то же место, но в Windows их вывод не перемешивается (как мы видели выше, пакет multiprocessing предоставляет также совместно используемый объект Lock, который при необходимости может использоваться для синхронизации процессов).

     Код завершения дочернего процесса доступен после его завершения в атрибуте exitcode.

Если запустить этот сценарий, главный процесс-потребитель будет сообщать о своих попытках извлечения данных из очереди, а дочерние процессы-производители (строки с отступами) будут выводить свои идентификаторы ID процессов и данные.

C:\…\PP4E\System\Processes> multi4.py

start 6296

no data

no data

@ 8008 101

posted: [8008, 101]

@ 6068 1

@ 3760 1001

posted: [6068, 1]

@ 8008 102

posted: [3760, 1001]

@ 6068 2

@ 3760 1002

posted: [8008, 102]

@ 8008 103

@ 8008 —

posted: [6068, 2]

@ 6068 3

@ 6068 —

@ 3760 1003

@ 3760 —

posted: [3760, 1002]

posted: [8008, 103]

posted: [6068, 3]

posted: [3760, 1003] finish 6296 0

А теперь представьте, что строки, начинающиеся с символа «@», являются результатами длительных операций, а остальные строки представляют отражение работы главного потока выполнения графического интерфейса; широта возможностей этого пакета наверняка станет для вас более очевидной.

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

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