ℹ️ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0.4 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html |
| Last Crawled | 2026-03-30 00:51:48 (12 days ago) |
| First Indexed | 2025-05-25 10:55:46 (10 months ago) |
| HTTP Status Code | 200 |
| Meta Title | multiprocessing — Процессный параллелизм — Документация Python 3.8.8 |
| Meta Description | null |
| Meta Canonical | null |
| Boilerpipe Text | Введение
¶
multiprocessing
- это пакет, который поддерживает порождение процессов с использованием
API, похожим на модуль
threading
. Пакет
multiprocessing
предлагает как локальный, так и удаленный параллелизм, эффективно обходя
Глобальную блокировку интерпретатора
с использованием
подпроцессов вместо потоков. Также модуль
multiprocessing
позволяет программисту полностью
использовать несколько процессоров на данном компьютере. Работает как на Unix, так и на Windows.
Модуль
multiprocessing
также вводит API, которые не имеет аналогов в модуле
threading
. Ярким примером этого является объект
Pool
, который
предлагает удобное средство параллелирования выполнения функции по множеству
входных значениц, распределения входных данных по процессам (параллелизм
данных). Следующий пример демонстрирует обычную практику определения таких
функций в модуле, чтобы дочерние процессы могли успешно импортировать этот
модуль. Этот базовый пример параллелизма данных с использованием
Pool
:
from
multiprocessing
import
Pool
def
f
(
x
):
return
x
*
x
if
__name__
==
'__main__'
:
with
Pool
(
5
)
as
p
:
print
(
p
.
map
(
f
,
[
1
,
2
,
3
]))
будет напечатано в стандартный вывод:
[
1
,
4
,
9
]
Класс
Process
¶
В
multiprocessing
процессы порождаются созданием объекта
Process
, а затем вызовом
его метода
start()
.
Process
следует API
threading.Thread
. Тривиальный
пример многопроцессорной программы:
from
multiprocessing
import
Process
def
f
(
name
):
print
(
'hello'
,
name
)
if
__name__
==
'__main__'
:
p
=
Process
(
target
=
f
,
args
=
(
'bob'
,))
p
.
start
()
p
.
join
()
Ниже приведен развернутый пример, показывающий соответствующие идентификаторы
отдельных процессов:
from
multiprocessing
import
Process
import
os
def
info
(
title
):
print
(
title
)
print
(
'module name:'
,
__name__
)
print
(
'parent process:'
,
os
.
getppid
())
print
(
'process id:'
,
os
.
getpid
())
def
f
(
name
):
info
(
'function f'
)
print
(
'hello'
,
name
)
if
__name__
==
'__main__'
:
info
(
'main line'
)
p
=
Process
(
target
=
f
,
args
=
(
'bob'
,))
p
.
start
()
p
.
join
()
Объяснение причины необходимости
if
__name__
==
'__main__'
части см. в разделе
Программирование рекомендаций
.
Контексты и методы запуска
¶
В зависимости от платформы,
multiprocessing
поддерживает три способа запуска
процесса. Далее перечислены
методы запуска
.
spawn
Родительский процесс запускает новый процесс интерпретатора Python. Дочерний
процесс унаследует только те ресурсы, которые необходимы для выполнения метода
run()
объекта процесса. В частности, ненужные файловые
дескрипторы и дескрипторы родительского процесса не будут унаследованы. Запуск
процесса с использованием этого метода довольно медленный по сравнению с
использованием
fork
или
forkserver
.
Доступно в Unix и Windows. Значение по умолчанию для Windows и macOS.
fork
Родительский процесс использует
os.fork()
для форсирования
Python интерпретатор. Дочерний процесс, когда он начинается, фактически
идентичен родительскому процессу. Все ресурсы родителя наследуются дочерним
процессом. Следует отметить, что безопасная форсировка многопоточного процесса
является проблематичной.
Доступно только в Unix. Значение по умолчанию в Unix.
forkserver
Когда программа начинает и выбирает метод начала
forkserver
,
процесс сервера, начат. С этого момента всякий раз, когда требуется новый
процесс, родительский процесс подключается к серверу и запрашивает, чтобы он
форсировал новый процесс. Процесс сервера вилки является однопотоковым, поэтому
он безопасен для использования
os.fork()
. Ненужные ресурсы не наследуются.
Доступный на платформах Unix, которые поддерживают мимолетный файл дескрипторы по
Unix пайпы.
Изменено в версии 3.8:
На macOS метод начала
spawn
- теперь дефолт. Метод запуска
fork
следует считать небезопасным, поскольку он может привести к сбоям подпроцессы.
См.
bpo-33725
.
Изменено в версии 3.4:
spawn
добавлены на всех платформах unix и
forkserver
добавлены для
некоторых платформ unix. Дочерние процессы больше не наследуют все
унаследованные родительские дескрипторы в Windows.
В Unix с помощью методов запуска
spawn
или
forkserver
также запускается
процесс
resource tracker
, который отслеживает несвязанные именованные системные
ресурсы (такие как именованные семафоры или
SharedMemory
объекты), созданные процессами программы. После завершения всех процессов средство отслеживания
ресурсов отменяет связь с любым оставшимся отслеживаемым объектом. Обычно их не
должно быть, но если какой-либо процесс был убит сигналом, то может возникнуть
некоторая «утечка» ресурсов. (Ни просочившиеся семафоры, ни сегменты общей
памяти не будут автоматически отключены до следующей перезагрузки. Это
проблематично для обоих объектов, поскольку система допускает только
ограниченное количество именованных семафоров, а сегменты совместно используемой
памяти занимают некоторое место в основной памяти.)
Для выбора метода запуска используется
set_start_method()
в
if
__name__
==
'__main__'
клаузула
основного модуля. Например:
import
multiprocessing
as
mp
def
foo
(
q
):
q
.
put
(
'hello'
)
if
__name__
==
'__main__'
:
mp
.
set_start_method
(
'spawn'
)
q
=
mp
.
Queue
()
p
=
mp
.
Process
(
target
=
foo
,
args
=
(
q
,))
p
.
start
()
print
(
q
.
get
())
p
.
join
()
set_start_method()
не должны быть используемый более одного раза в программе.
Кроме того, можно использовать
get_context()
для получения объекта контекст.
Объекты контекста имеют тот же API, что и модуль многопроцессорной обработки, и
позволяют использовать несколько методов запуска в одной программе:
import
multiprocessing
as
mp
def
foo
(
q
):
q
.
put
(
'hello'
)
if
__name__
==
'__main__'
:
ctx
=
mp
.
get_context
(
'spawn'
)
q
=
ctx
.
Queue
()
p
=
ctx
.
Process
(
target
=
foo
,
args
=
(
q
,))
p
.
start
()
print
(
q
.
get
())
p
.
join
()
Обратите внимание, что объекты, связанные с одним контекст, могут быть
несовместимы с процессами для другого контекст. В частности, блокировки,
созданные с помощью
fork
контекст, не могут быть переданы процессам,
запущенным с помощью методов запуска
spawn
или
forkserver
.
Библиотека, которая хочет использовать конкретный метод запуска, должна,
вероятно, использовать
get_context()
, чтобы избежать вмешательства в выбор
пользователя библиотеки.
Предупреждение
Стартовые методы
'spawn'
и
'forkserver'
в настоящее время не могут быть
используемый с «замороженными» исполняемыми файлами (т.е. двоичными файлами,
создаваемыми пакетами, такими как
PyInstaller
and
cx_Freeze
) в Unix.
Стартовый метод
'fork'
работает.
Обмен объектами между процессами
¶
multiprocessing
поддерживает два типа каналов связи между процессами:
Очереди
Класс
Queue
является близким клоном
queue.Queue
. Например:
from
multiprocessing
import
Process
,
Queue
def
f
(
q
):
q
.
put
([
42
,
None
,
'hello'
])
if
__name__
==
'__main__'
:
q
=
Queue
()
p
=
Process
(
target
=
f
,
args
=
(
q
,))
p
.
start
()
print
(
q
.
get
())
# распечатает "[42, None, 'hello']"
p
.
join
()
Очереди поток и безопасны для обработки.
Пайпы
Pipe()
функционируют возвращает пара объектов связи, связанных пайп,
который по умолчанию является (двухсторонним) дуплексом. Например:
from
multiprocessing
import
Process
,
Pipe
def
f
(
conn
):
conn
.
send
([
42
,
None
,
'hello'
])
conn
.
close
()
if
__name__
==
'__main__'
:
parent_conn
,
child_conn
=
Pipe
()
p
=
Process
(
target
=
f
,
args
=
(
child_conn
,))
p
.
start
()
print
(
parent_conn
.
recv
())
# распечатает "[42, None, 'hello']"
p
.
join
()
Два объекта соединения возвращенный
Pipe()
представляют два конца
пайп. Каждый объект подключения имеет методы
send()
и
recv()
(среди прочих). Обратите внимание, что данные в пайп могут быть
повреждены, если два процесса (или потоки) пытаются одновременно считать
или записывать в
same
конец пайп. Конечно, нет риска коррупции от
процессов, использующих разные концы пайп одновременно.
Синхронизация между процессами
¶
multiprocessing
содержит эквиваленты всех примитивов синхронизации из
threading
.
Для сущность можно использовать блокировку для обеспечения одновременной
печати только одного процесса в стандартный вывод:
from
multiprocessing
import
Process
,
Lock
def
f
(
l
,
i
):
l
.
acquire
()
try
:
print
(
'hello world'
,
i
)
finally
:
l
.
release
()
if
__name__
==
'__main__'
:
lock
=
Lock
()
for
num
in
range
(
10
):
Process
(
target
=
f
,
args
=
(
lock
,
num
))
.
start
()
Без использования блокировки выходные данные различных процессов могут быть
смешаны.
Совместное использование состояние между процессами
¶
Как упомянуто выше, когда выполнение параллельного программирования его является
обычно лучшим избегать использования разделенного состояние в максимально
возможной степени. Это особенно верно при использовании нескольких процессов.
Однако, если вам действительно нужно использовать некоторые общие данные, то
multiprocessing
предоставляет пару способов сделать это.
Общая память
Данные могут храниться в карте совместно используемой памяти с помощью
Value
или
Array
. Например, следующие код:
from
multiprocessing
import
Process
,
Value
,
Array
def
f
(
n
,
a
):
n
.
value
=
3.1415927
for
i
in
range
(
len
(
a
)):
a
[
i
]
=
-
a
[
i
]
if
__name__
==
'__main__'
:
num
=
Value
(
'd'
,
0.0
)
arr
=
Array
(
'i'
,
range
(
10
))
p
=
Process
(
target
=
f
,
args
=
(
num
,
arr
))
p
.
start
()
p
.
join
()
print
(
num
.
value
)
print
(
arr
[:])
напечатает:
3.1415927
[
0
,
-
1
,
-
2
,
-
3
,
-
4
,
-
5
,
-
6
,
-
7
,
-
8
,
-
9
]
Аргументы
'd'
и
'i'
используемый при создании
num
и
arr
являются типкодами вида используемый модулем
array
:
'd'
указывает двойную точность float и
'i'
обозначает целое число со
знаком. Эти общие объекты будут процессом и потокобезопасной.
Для большей гибкости в использовании совместно используемой памяти можно
использовать модуль
multiprocessing.sharedctypes
, поддерживающий создание объектов произвольных
ctypes, выделенных из совместно используемой памяти.
Серверный процесс
Объект менеджера возвращенный
Manager()
управляет серверным процессом, который
содержит объекты Python и позволяет другим процессам манипулировать ими с
помощью прокси.
Менеджер возвращенный
Manager()
поддержит типы
list
,
dict
,
Namespace
,
Lock
,
RLock
,
Semaphore
,
BoundedSemaphore
,
Condition
,
Event
,
Barrier
,
Queue
,
Value
и
Array
. Например,:
from
multiprocessing
import
Process
,
Manager
def
f
(
d
,
l
):
d
[
1
]
=
'1'
d
[
'2'
]
=
2
d
[
0.25
]
=
None
l
.
reverse
()
if
__name__
==
'__main__'
:
with
Manager
()
as
manager
:
d
=
manager
.
dict
()
l
=
manager
.
list
(
range
(
10
))
p
=
Process
(
target
=
f
,
args
=
(
d
,
l
))
p
.
start
()
p
.
join
()
print
(
d
)
print
(
l
)
напечатает:
{
0.25
:
None
,
1
:
'1'
,
'2'
:
2
}
[
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
]
Менеджеры серверных процессов более гибки, чем использование общих объектов
памяти, поскольку они могут быть созданы для поддержки произвольных типов
объектов. Кроме того, один менеджер может совместно использоваться процессами на
разных компьютерах по сети. Однако они работают медленнее, чем совместно
используемая память.
Использование пула воркеров
¶
Класс
Pool
представляет пул рабочих процессов. Он содержит методы,
позволяющие выгружать задачи в рабочие процессы несколькими различными
способами.
Например:
from
multiprocessing
import
Pool
,
TimeoutError
import
time
import
os
def
f
(
x
):
return
x
*
x
if
__name__
==
'__main__'
:
# запуск 4 рабочих процессов
with
Pool
(
processes
=
4
)
as
pool
:
# печать "[0, 1, 4,..., 81]"
print
(
pool
.
map
(
f
,
range
(
10
)))
# печатать одинаковые числа в произвольном порядке
for
i
in
pool
.
imap_unordered
(
f
,
range
(
10
)):
print
(
i
)
# вычислить "f(20)" асинхронно
res
=
pool
.
apply_async
(
f
,
(
20
,))
# запускается в *только* одном процессе
print
(
res
.
get
(
timeout
=
1
))
# печатает "400"
# вычислить "os.getpid()" асинхронно
res
=
pool
.
apply_async
(
os
.
getpid
,
())
# запускается в *только* одном процессе
print
(
res
.
get
(
timeout
=
1
))
# печатает PID этого процесса
# запуск нескольких оценок асинхронно *может* использовать больше процессов
multiple_results
=
[
pool
.
apply_async
(
os
.
getpid
,
())
for
i
in
range
(
4
)]
print
([
res
.
get
(
timeout
=
1
)
for
res
in
multiple_results
])
# уснуть одному рабочему на 10 секунд
res
=
pool
.
apply_async
(
time
.
sleep
,
(
10
,))
try
:
print
(
res
.
get
(
timeout
=
1
))
except
TimeoutError
:
print
(
"We lacked patience and got a multiprocessing.TimeoutError"
)
print
(
"For the moment, the pool remains available for more work"
)
# выход из блока with с остановкой пула
print
(
"Now the pool is closed and no longer available"
)
Обратите внимание, что методы бассейна должны только когда-либо быть используемый
процессом, который создал его.
Примечание
Функциональность этого пакета требует, чтобы модуль
__main__
был импортирован
нижестоящими элементами. Это освещено в
Программирование рекомендаций
, однако здесь стоит указать.
Это означает, что некоторые примеры, такие как примеры
multiprocessing.pool.Pool
не будут
работать в интерактивном интерпретатор. Например:
>>>
>>>
from
multiprocessing
import
Pool
>>>
p
=
Pool
(
5
)
>>>
def
f
(
x
):
...
return
x
*
x
...
>>>
with
p
:
...
p
.
map
(
f
,
[
1
,
2
,
3
])
Process PoolWorker-1:
Process PoolWorker-2:
Process PoolWorker-3:
Traceback (most recent call last):
AttributeError
:
'module' object has no attribute 'f'
AttributeError: 'module' object has no attribute 'f'
AttributeError: 'module' object has no attribute 'f'
(Если попробовать это, то на самом деле будет выведено три полных трейсбэки,
перемежающихся полуслучайным образом, а затем, возможно, придется как-то
остановить родительский процесс.
Ссылка
¶
Пакет
multiprocessing
в основном реплицирует API модуля
threading
.
Process
и исключения
¶
class
multiprocessing.
Process
(
group=None
,
target=None
,
name=None
,
args=()
,
kwargs={}
,
*
,
daemon=None
)
¶
Объекты процесса представляют собой операцию, выполняемую в отдельном процессе.
Класс
Process
имеет эквиваленты всех методов
threading.Thread
.
Конструктор всегда должен вызываться с аргументами ключевой.
group
всегда должны быть
None
; он существует исключительно для совместимости с
threading.Thread
.
target
- вызываемый объект, вызываемый методом
run()
. По
умолчанию он имеет значение
None
, то есть ничего не называется.
name
- имя процесса (более подробную информацию см. в разделе
name
).
args
- кортеж аргументов для целевого вызова.
kwargs
-
словарь ключевой аргументов для целевого вызова. Если указано, только ключевой
аргумент
daemon
задает для флага процесса
daemon
значение
True
или
False
. Если значение равно
None
(по умолчанию), этот
флаг наследуется от процесса создания.
По умолчанию аргументы не передаются
target
.
Если подкласс отвергает конструктора, он должен удостовериться, что призывает
конструктора базового класса (
Process.__init__()
) прежде, чем сделать что-либо еще к
процессу.
Изменено в версии 3.3:
Добавлен аргумент
daemon
.
run
(
)
¶
Метод, представляющий активность процесса.
Этот метод можно переопределить в подкласс. Стандартный метод
run()
призывает подлежащий выкупу объект, переданный конструктору объекта как целевой
аргумент, если таковые имеются, с последовательными и аргументами ключевой,
взятыми от
args
и аргументов
kwargs
, соответственно.
start
(
)
¶
Запустите действие процесса.
Это должно вызываться не более одного раза для каждого объекта процесса. Она
обеспечивает возможность вызова метода
run()
объекта в отдельном процессе.
join
(
[
timeout
]
)
¶
Если необязательным аргументом
timeout
является
None
(по умолчанию),
метод блокируется до завершения процесса, метод
join()
которого вызывается.
Если
timeout
- положительное число, оно блокируется максимум через
timeout
секунд. Обратите внимание, что метод возвращает
None
, если его процесс
завершается или время ожидания метода истекло. Проверьте
exitcode
процесса,
чтобы определить его завершение.
Процесс может быть объединен много раз.
Процесс не может присоединиться к самому себе, поскольку это приведет к
взаимоблокировке. Ошибка при попытке присоединения к процессу перед его
запуском.
name
¶
Имя процесса. Имя - строка используемый в идентификационных целях только. У
него нет семантики. Нескольким процессам может быть присвоено одно и то же имя.
Начальное имя задается конструктором. Если для конструктора не указано явное
имя, создается имя формы „Process-N:sub:
1
: N:sub:
2
:…:
N:sub:
k
“, где каждый N
k
является N-м потомком своего родителя.
is_alive
(
)
¶
Возвращает жив ли процесс.
Примерно, объект процесса жив с момента возвращает метода
start()
до
завершения дочернего процесса.
daemon
¶
Флаг демона процесса, логический значение. Это должно быть установлено,
прежде чем
start()
называют.
Начальный значение унаследован от процесса создания.
Когда процесс завершается, он пытается завершить все свои демонические дочерние
процессы.
Обратите внимание, что демоническому процессу запрещено создавать дочерние
процессы. В противном случае демонический процесс оставит своих потомков
сиротами, если он завершится после завершения родительского процесса. Кроме
того, это демоны или службы
не
Unix, это обычные процессы, которые
будут прекращены (и не присоединены), если не демонические процессы вышли.
В дополнение к
threading.Thread
API объекты
Process
также поддерживают следующий
атрибуты и methods:
pid
¶
Возвращает идентификатор процесса. Перед началом процесса это будет
None
.
exitcode
¶
Выход ребенка код. Это будет
None
, если процесс еще не завершен.
Отрицательный значение
-N
указывает на то, что дочерний объект был
завершен сигналом
N
.
authkey
¶
Ключ аутентификации процесса (байтовая строка).
Когда
multiprocessing
инициализируется, основному процессу присваивается случайный
строка с помощью
os.urandom()
.
При создании объекта
Process
он наследует ключ аутентификации родительского
процесса, хотя его можно изменить, установив для параметра
authkey
значение
другого байта строка.
См.
Ключи аутентификации
.
sentinel
¶
Числовой дескриптор системного объекта, который становится «готовым» по
завершении процесса.
Вы можете использовать этот значение, если вы хотите ждать на нескольких
событиях, сразу используя
multiprocessing.connection.wait()
. В противном случае
вызов
join()
проще.
В Windows это дескриптор ОС, используемый с семейством вызовов API
WaitForSingleObject
и
WaitForMultipleObjects
. На Unix это - файл дескриптор, применимый с примитивами от модуля
select
.
Добавлено в версии 3.3.
terminate
(
)
¶
Завершить процесс. В Unix это выполняется с помощью сигнала
SIGTERM
; на
Windows используется
TerminateProcess()
. Следует отметить, что
обработчики exit и finally и т.д. выполняться не будут.
Заметим, что потомки процесса
не
будут прекращены - они просто
осиротеют.
Предупреждение
Если этот метод является используемый, когда связанный процесс использует
пайп или очередь, то пайп или очередь может быть повреждена и
может стать непригодной для использования другим процессом. Аналогично, если
процесс приобрел блокировку или семафор и т.д., то завершение его может привести
к взаимоблокировке других процессов.
kill
(
)
¶
То же, что и
terminate()
, но с использованием сигнала
SIGKILL
в Unix.
Добавлено в версии 3.7.
close
(
)
¶
Закрыть объект
Process
, освободив все связанные с ним ресурсы.
ValueError
возникает, если базовый процесс все еще выполняется. Как только
close()
возвращает успешно, большинство других методов и атрибуты объекта
Process
поднимут
ValueError
.
Добавлено в версии 3.7.
Обратите внимание, что
start()
,
join()
,
is_alive()
,
terminate()
и
методы
exitcode
должен только вызвать процесс, который создал объект
процесса.
Пример использования некоторых методов
Process
:
>>> import multiprocessing, time, signal
>>> p = multiprocessing.Process(target=time.sleep, args=(1000,))
>>> print(p, p.is_alive())
<Process ... initial> False
>>> p.start()
>>> print(p, p.is_alive())
<Process ... started> True
>>> p.terminate()
>>> time.sleep(0.1)
>>> print(p, p.is_alive())
<Process ... stopped exitcode=-SIGTERM> False
>>> p.exitcode == -signal.SIGTERM
True
exception
multiprocessing.
ProcessError
¶
Базовый класс всех исключений
multiprocessing
.
exception
multiprocessing.
BufferTooShort
¶
Исключение, вызванное
Connection.recv_bytes_into()
, когда предоставленный объект буфера слишком
мал для чтения сообщения.
Если
e
является сущность
BufferTooShort
, то
e.args[0]
передаст
сообщение в виде байтовой строки.
exception
multiprocessing.
AuthenticationError
¶
Возникает при ошибке проверки подлинности.
exception
multiprocessing.
TimeoutError
¶
Вызывается методами с тайм-аутом по истечении тайм-аута.
Пайпы и очереди
¶
При использовании нескольких процессов обычно используют передачу сообщений для
связи между процессами и избегают необходимости использования каких-либо
примитивов синхронизации, таких как блокировки.
Для передачи сообщений можно использовать
Pipe()
(для соединения между
двумя процессами) или очередь (которая позволяет нескольким производителям и
потребителям).
Queue
,
SimpleQueue
и типы
JoinableQueue
- мультипроизводитель,
мультипотребитель очереди
FIFO
, смоделированные на классе
queue.Queue
в
стандартной библиотеке. Они отличаются по тому
Queue
, испытывает
недостаток в
task_done()
и методах
join()
, введенных в класс Python
2.5’s
queue.Queue
.
Если вы используете
JoinableQueue
, то вы
должны
вызвать
JoinableQueue.task_done()
для
каждой задачи, удаленной из очереди, или семафор используемый для подсчета
количества незавершенных задач может в конечном итоге переполниться, вызывая
исключение.
Обратите внимание, что можно также создать общую очередь с помощью объекта
менеджера - см. раздел
Менеджеры
.
Примечание
Когда объект помещен на очередь, объект - pickled и фон поток более
поздние потоки данные pickled к основному пайп. Это имеет некоторые
последствия, которые немного удивительны, но не должны вызывать никаких
практических трудностей - если они действительно беспокоят вас, то вы можете
вместо этого использовать очередь, созданную с
manager
.
После помещения объекта в пустую очередь может произойти бесконечная
задержка перед тем, как метод
empty()
очереди возвращает
False
и
get_nowait()
может возвращает без повышения
queue.Empty
.
если несколько процессов ставят в очередь объекты, возможно, чтобы объекты
были приняты на другом конце вне порядка. Однако объекты, поставленные в очередь
одним и тем же процессом, всегда будут находиться в ожидаемом порядке
относительно друг друга.
Предупреждение
Если процесс был убит с помощью
Process.terminate()
или
os.kill()
во
время попытки использования
Queue
, то данные в очереди, вероятно, будут
повреждены. Это может привести к тому, что любой другой процесс получит
исключение при попытке использовать очередь позже.
Предупреждение
Как упомянуто выше, если дочерний процесс поместил предметы на очередь (и у него
нет используемый
JoinableQueue.cancel_join_thread
),
тогда тот процесс не закончится,
пока все буферизированные предметы не смылись (flushed) в пайп.
Это означает, что при попытке присоединения к этому процессу может возникнуть
взаимоблокировка, если вы не уверены, что все элементы, помещенные в очередь,
были израсходованы. Аналогично, если дочерний процесс не является демоническим,
то родительский процесс может зависать на выходе, когда пытается присоединиться
ко всем своим недемоническим потомкам.
Обратите внимание, что очередь, созданная с помощью менеджера, не имеет этой
проблемы. См.
Программирование рекомендаций
.
Пример использования очередей для межпроцессной связи см. в разделе
Примеры
.
multiprocessing.
Pipe
(
[
duplex
]
)
¶
Возвращает пару
(conn1,
conn2)
объектов
Connection
,
представляющих концы пайпа.
Если
duplex
равно
True
(по умолчанию), то пайп является
двунаправленным. Если
duplex
-
False
тогда, пайп однонаправлен:
conn1
может только быть используемый для получения сообщений, и
conn2
может только быть используемый для отправки сообщений.
class
multiprocessing.
Queue
(
[
maxsize
]
)
¶
Возвращает общую очередь процесса, реализованную с использованием пайп и
нескольких блокировок/семафоров. Когда процесс сначала помещает элемент в
очередь, запускается питатель поток, который передает объекты из буфера в
пайп.
Обычные исключения
queue.Empty
и
queue.Full
из модуля
queue
стандартной
библиотеки вызываются тайм-аутами сигнала.
Queue
реализует все методы
queue.Queue
, кроме
task_done()
и
join()
.
qsize
(
)
¶
Возвращает приблизительный размер очереди. Из-за семантики
многопоточной/многопроцессорной обработки это число не является надежным.
Обратите внимание, что это может привести к появлению
NotImplementedError
на платформах
Unix, таких как Mac OS X, где
sem_getvalue()
не реализован.
empty
(
)
¶
Возвращает
True
, если очередь пуста,
False
иначе. Из-за семантики
многопоточной/многопроцессорной обработки это ненадежно.
full
(
)
¶
Возвращает
True
, если очередь полна,
False
иначе. Из-за семантики
многопоточной/многопроцессорной обработки это ненадежно.
put
(
obj
[
,
block
[
,
timeout
]
]
)
¶
Поместить объект в очередь. Если дополнительный аргумент
block
имеет
значение
True
(по умолчанию), а
timeout
- значение
None
(по
умолчанию), при необходимости блокируйте до тех пор, пока свободный слот не
будет доступен. Если
timeout
является положительным числом, он блокирует
максимум
timeout
секунд и вызывает исключение
queue.Full
, если свободный
слот не был доступен в течение этого времени. В противном случае (
block
-
False
) Поместить элемент в очередь, если свободный слот немедленно
доступен, иначе вызовите исключение
queue.Full
(
timeout
игнорируется в этом
случае).
put_nowait
(
obj
)
¶
Эквивалентный
put(obj,
False)
.
get
(
[
block
[
,
timeout
]
]
)
¶
Удаление и возвращает элемента из очереди. Если необязательными args
block
является
True
(по умолчанию), а
timeout
-
None
(по
умолчанию), при необходимости блокируйте до тех пор, пока элемент не будет
доступен. Если
timeout
является положительным числом, он блокирует максимум
timeout
секунд и вызывает исключение
queue.Empty
, если за это время не было
доступно ни одного элемента. В противном случае (блок -
False
),
возвращает элемент, если он немедленно доступен, иначе вызовите исключение
queue.Empty
(в этом случае
timeout
игнорируется).
Изменено в версии 3.8:
Если очередь закрыта,
ValueError
поднят вместо
OSError
.
get_nowait
(
)
¶
Эквивалентный
get(False)
.
multiprocessing.Queue
имеет несколько дополнительных методов, не
найденных в
queue.Queue
.
Эти методы обычно не нужны для большинства код:
close
(
)
¶
Укажите, что текущий процесс больше не будет помещать данные в эту очередь.
Фоновый поток завершит работу после очистки всех буферизованных данных в
пайп. Это вызывается автоматически при сборе мусора в очередь.
join_thread
(
)
¶
Присоединиться к фоновому потоку. Это может только быть используемый после
того, как вызван
close()
. Это блокирует до фона выходы поток,
гарантируя, что все данные в буфере смылись (flushed) в пайп.
По умолчанию, если процесс не является создателем очереди, при выходе он
попытается присоединиться к фоновому поток очереди. Процесс может вызвать
cancel_join_thread()
, чтобы заставить
join_thread()
ничего не делать.
cancel_join_thread
(
)
¶
Препятствуйте тому, чтобы
join_thread()
блокировал. В частности, это предотвращает
автоматическое соединение фоновых поток при завершении процесса – см.
раздел
join_thread()
.
Лучшее имя для этого метода может быть
allow_exit_without_flush()
. Вероятно, это приведет к
потере поставленных в очередь данных, и вам почти наверняка не потребуется их
использовать. Это действительно только в том случае, если необходимо, чтобы
текущий процесс немедленно вышел, не дожидаясь очистки поставленных в очередь
данных на основной пайп, и вы не заботитесь о потерянных данных.
Примечание
Функциональность этого класса требует функциональной реализации общего семафора
в операционной системе хоста. Без него функциональность этого класса будет
отключена, и попытки создания экземпляра
Queue
приведут к появлению
ImportError
. Дополнительные сведения см. в разделе
bpo-3770
. То же самое
относится и к любому из перечисленных ниже типов специализированных очередей.
class
multiprocessing.
SimpleQueue
¶
Это упрощенный тип
Queue
, очень близкий к заблокированному
Pipe
.
empty
(
)
¶
Возвращает
True
, если очередь пуста,
False
иначе.
get
(
)
¶
Удаление и возвращает элемента из очереди.
put
(
item
)
¶
Поместить
item
в очередь.
class
multiprocessing.
JoinableQueue
(
[
maxsize
]
)
¶
JoinableQueue
,
Queue
подкласс, представляет собой очередь, которая
дополнительно содержит методы
task_done()
и
join()
.
task_done
(
)
¶
Укажите, что ранее поставленная в очередь задача завершена. Используется
потребителями очереди. Для каждого
get()
используемый, чтобы выбрать задачу,
последующий вызов
task_done()
сообщает очереди, что обработка задачи завершена.
Если
join()
в настоящее время заблокирует, то он возобновит, когда все
предметы были обработаны (подразумевать, что требование
task_done()
было получено
для каждого предмета, который был
put()
в очередь).
Вызывает
ValueError
, если вызывается больше раз, чем было элементов, помещенных
в очередь.
join
(
)
¶
Блокировать до тех пор, пока все элементы в очереди не будут получены и
обработаны.
Количество незавершенных задач увеличивается при каждом добавлении элемента в
очередь. Счетчик снижается всякий раз, когда потребитель звонит
task_done()
,
чтобы указать, что элемент был извлечен, и вся работа над ним завершена. Когда
число незавершенных задач падает до нуля,
join()
разблокирует.
Разное
¶
multiprocessing.
active_children
(
)
¶
Возвращает список всех живых потомков текущего процесса.
Вызов этого метода имеет побочный эффект «присоединения» к любым уже завершенным
процессам.
multiprocessing.
cpu_count
(
)
¶
Возвращает количество ЦПУ в системе.
Это число не эквивалентно числу ЦПУ, которые может использовать текущий процесс.
Количество используемых ЦПУ можно получить с помощью
len(os.sched_getaffinity(0))
Может поднять
NotImplementedError
.
multiprocessing.
current_process
(
)
¶
Возвращает объект
Process
, соответствующий текущему процессу.
Аналог
threading.current_thread()
.
multiprocessing.
parent_process
(
)
¶
Возвращает объект
Process
, соответствующий родительскому процессу
current_process()
. Для основного процесса
parent_process
будет
None
.
Добавлено в версии 3.8.
multiprocessing.
freeze_support
(
)
¶
Добавление поддержки в том случае, если программа, использующая
multiprocessing
,
была заморожена для создания исполняемого файла Windows. (Был проверен с помощью
py2exe
,
PyInstaller
и
cx_Freeze
.)
Эту функцию необходимо вызвать непосредственно после
if
__name__
==
'__main__'
линии основного
модуля. Например:
from
multiprocessing
import
Process
,
freeze_support
def
f
():
print
(
'hello world!'
)
if
__name__
==
'__main__'
:
freeze_support
()
Process
(
target
=
f
)
.
start
()
Если строка
freeze_support()
опущена, то попытка запуска замороженного исполняемого
файла вызовет
RuntimeError
.
freeze_support()
запроса не имеет никакого эффекта, когда он призван на любую
операционную систему кроме Windows. Кроме того, если модулем управляет обычно
Python интерпретатор на Windows (программа не была заморожена), то
freeze_support()
не имеет никакого эффекта.
multiprocessing.
get_all_start_methods
(
)
¶
Возвращает список поддерживаемых методов запуска, первым из которых является
метод по умолчанию. Возможные методы запуска:
'fork'
,
'spawn'
и
'forkserver'
. В Windows доступен только
'spawn'
. На Unix
'fork'
и
'spawn'
всегда поддерживаются, при этом
'fork'
- дефолт.
Добавлено в версии 3.4.
multiprocessing.
get_context
(
method=None
)
¶
Возвращает объект контекст, имеющий ту же атрибуты, что и модуль
multiprocessing
.
Если
method
-
None
тогда дефолт, контекст - возвращенный. В
противном случае
method
должны быть
'fork'
,
'spawn'
,
'forkserver'
.
ValueError
возникает, если указанный метод запуска недоступен.
Добавлено в версии 3.4.
multiprocessing.
get_start_method
(
allow_none=False
)
¶
Возвращает имя метода запуска используемый для запуска процессов.
Если метод начала не был исправлен, и
allow_none
ложный, то метод начала
прикреплен к дефолту, и имя - возвращенный. Если метод запуска не был фиксирован,
а
allow_none
имеет значение true, то
None
имеет значение возвращенный.
возвращает значение может быть
'fork'
,
'spawn'
,
'forkserver'
или
None
.
'fork'
является значением по умолчанию в Unix, а
'spawn'
-
значением по умолчанию в Windows.
Добавлено в версии 3.4.
multiprocessing.
set_executable
(
)
¶
Задает путь к Python интерпретатор, который будет использоваться при запуске
дочернего процесса. (По умолчанию
sys.executable
- используемый). Встраивающие
устройства, вероятно, должны будут сделать что-то вроде:
set_executable
(
os
.
path
.
join
(
sys
.
exec_prefix
,
'pythonw.exe'
))
прежде чем они смогут создавать дочерние процессы.
Изменено в версии 3.4:
Теперь поддержанный на Unix, когда метод начала
'spawn'
- используемый.
multiprocessing.
set_start_method
(
method
)
¶
Установите метод, который должен быть используемый, чтобы начать дочерние
процессы.
method
может быть
'fork'
,
'spawn'
или
'forkserver'
.
Следует отметить, что это должно вызываться не более одного раза и должно быть
защищено внутри
if
__name__
==
'__main__'
клаузула основного модуля.
Добавлено в версии 3.4.
Объекты связи
¶
Объекты соединения позволяют отправлять и принимать выбираемые объекты или
строки. Они могут рассматриваться как связанные сокеты, ориентированные
на сообщение.
Объекты соединения обычно создаются с помощью
Pipe
– см. также раздел
Слушатели и клиенты
.
class
multiprocessing.connection.
Connection
¶
send
(
obj
)
¶
Отправьте объект на другой конец соединения, который следует прочитать с помощью
команды
recv()
.
Объект должен быть подбираемым. Очень большие огурцы (приблизительно 32
MiB +, хотя это зависит от ОС) могут вызвать исключение
ValueError
.
recv
(
)
¶
Возвращает объект, отправленный с другого конца соединения с помощью команды
send()
. Блокируется, пока не будет что получить. Поднимает
EOFError
,
если ничего не осталось получить, а другой конец был закрыт.
fileno
(
)
¶
Возвращает файл дескриптор или дескриптор используемый по соединению.
close
(
)
¶
Закрыть связь.
Это вызывается автоматически при сборе мусора соединения.
poll
(
[
timeout
]
)
¶
Возвращает, имеются ли данные, доступные для чтения.
Если
timeout
не указан, то он будет возвращает немедленно. Если
timeout
- число, это указывает максимальное время блокировки в секундах. Если
timeout
None
, то бесконечное время ожидания равно используемый.
Следует отметить, что несколько объектов соединения могут опрашиваться
одновременно с помощью функции
multiprocessing.connection.wait()
.
send_bytes
(
buffer
[
,
offset
[
,
size
]
]
)
¶
Отправка байтовых данных из
байтоподобного объекта
в виде полного сообщения.
Если задано значение
offset
, то данные считываются из этой позиции в
buffer
. Если задано значение
size
, то многие байты будут считываться
из буфера. Очень большие буферы (приблизительно 32 MiB +, хотя это
зависит от ОС) могут вызвать исключение
ValueError
recv_bytes
(
[
maxlength
]
)
¶
Возвращает полное сообщение байтовых данных, отправленное с другого конца
соединения в виде строка. Блокируется, пока не будет что получить.
Поднимает
EOFError
, если ничего не осталось получить, а другой конец закрылся.
Если задано значение
maxlength
, и сообщение длиннее
maxlength
, то
OSError
возникает, и соединение будет недоступно для чтения.
Изменено в версии 3.3:
Используемая функция поднимает
IOError
, которое теперь является алиасом
OSError
.
recv_bytes_into
(
buffer
[
,
offset
]
)
¶
Считывание в
buffer
полного сообщения байтовых данных, отправленных с
другого конца соединения, и возвращает количества байтов в сообщении.
Блокируется, пока не будет что получить. Поднимает
EOFError
, если ничего не
осталось получить, а другой конец был закрыт.
buffer
должен быть записываемым
байтоподобным объектом
.
Если задано значение
offset
, то сообщение будет записано в буфер из этой позиции. Смещение
должно быть неотрицательным целым числом, меньшим длины
buffer
(в байтах).
Если буфер слишком короткий, то возникает исключение
BufferTooShort
и полное
сообщение доступно как
e.args[0]
где
e
- исключение сущность.
Изменено в версии 3.3:
Сами объекты соединения теперь могут переноситься между процессами с помощью
Connection.send()
и
Connection.recv()
.
Например:
>>>
>>>
from
multiprocessing
import
Pipe
>>>
a
,
b
=
Pipe
()
>>>
a
.
send
([
1
,
'hello'
,
None
])
>>>
b
.
recv
()
[1, 'hello', None]
>>>
b
.
send_bytes
(
b
'thank you'
)
>>>
a
.
recv_bytes
()
b'thank you'
>>>
import
array
>>>
arr1
=
array
.
array
(
'i'
,
range
(
5
))
>>>
arr2
=
array
.
array
(
'i'
,
[
0
]
*
10
)
>>>
a
.
send_bytes
(
arr1
)
>>>
count
=
b
.
recv_bytes_into
(
arr2
)
>>>
assert
count
==
len
(
arr1
)
*
arr1
.
itemsize
>>>
arr2
array('i', [0, 1, 2, 3, 4, 0, 0, 0, 0, 0])
Предупреждение
Метод
Connection.recv()
автоматически отключает полученные данные, что
может быть угрозой безопасности, если вы не можете доверять процессу,
отправившему сообщение.
Поэтому, если объект подключения не был создан с помощью
Pipe()
, следует
использовать методы
recv()
и
send()
только
после выполнения той или иной аутентификации. См.
Ключи аутентификации
.
Предупреждение
Если процесс погибает, когда он пытается прочитать или записать в пайп, то
данные в пайп, вероятно, будут повреждены, поскольку может оказаться невозможным
убедиться, где лежат границы сообщения.
Примитивы синхронизации
¶
Обычно примитивы синхронизации не так необходимы в многопроцессорной программе,
как в многопоточной программе. См. документацию по модулю
threading
.
Обратите внимание, что можно также создать примитивы синхронизации с помощью
объекта менеджера - см. раздел
Менеджеры
.
class
multiprocessing.
Barrier
(
parties
[
,
action
[
,
timeout
]
]
)
¶
Объект барьер: клон
threading.Barrier
.
Добавлено в версии 3.3.
class
multiprocessing.
BoundedSemaphore
(
[
value
]
)
¶
Барьерный семафорный объект: близкий аналог
threading.BoundedSemaphore
.
Существует одиночное отличие от его близкого аналога: первый аргумент его метода
acquire
называется
block
, как это согласуется с
Lock.acquire()
.
Примечание
В Mac OS X это неотличимо от
Semaphore
, потому что
sem_getvalue()
не реализована
на этой платформе.
class
multiprocessing.
Condition
(
[
lock
]
)
¶
Переменная условия: алиас для
threading.Condition
.
Если задано значение
lock
, то это должен быть объект
Lock
или
RLock
из
multiprocessing
.
Изменено в версии 3.3:
Добавлен метод
wait_for()
.
class
multiprocessing.
Event
¶
Клон
threading.Event
.
class
multiprocessing.
Lock
¶
Нерекурсивный объект блокировки: близкий аналог
threading.Lock
. Как только процесс
или поток приобрел блокировку, последующие попытки получить ее от любого
процесса или поток будут блокироваться до тех пор, пока она не будет
освобождена; любой процесс или поток может освободить его. Понятия и
поведение
threading.Lock
в том виде, в каком они применяются к потоки,
воспроизводятся здесь в
multiprocessing.Lock
, как это применимо к процессам или
потоки, за исключением отмеченных.
Обратите внимание, что
Lock
- на самом деле фабричная функция, какой
возвращает сущность
multiprocessing.synchronize.Lock
инициализировал с дефолтом контекст.
Lock
поддерживает протокол
контекстного менеджера
и таким образом может быть
используемый в
with
инструкции.
acquire
(
block=True
,
timeout=None
)
¶
Получить блокировку, блокировку или неблокировку.
Если для аргумента
block
установлено значение
True
(значение по
умолчанию), вызов метода будет блокироваться до тех пор, пока блокировка не
окажется в разблокированном состояние, а затем будет установлен параметр locked
и возвращает
True
. Обратите внимание, что имя этого первого аргумента
отличается от имени в
threading.Lock.acquire()
.
Если для аргумента
block
установлено значение
False
, вызов метода не
блокируется. Если блокировка в данный момент находится в заблокированном
состояние, возвращает
False
; в противном случае установите блокировку на
заблокированный состояние и возвращает
True
.
При вызове с положительным значение с плавающей запятой для
timeout
блок
максимум на количество секунд, указанное параметром
timeout
, если блокировка
не может быть получена. Просьбы с отрицательным значение для
timeout
эквивалентны
timeout
ноля. Вызовы с
timeout
значение
None
(по
умолчанию) устанавливают период тайм-аута как бесконечный. Отметим, что лечение
отрицательного или
None
значения для
timeout
отличается от
реализованного поведения в
threading.Lock.acquire()
. Аргумент
timeout
не имеет
практических последствий, если аргумент
block
имеет значение
False
и,
таким образом, игнорируется. Возвращает
True
если блокировка была
приобретена или
False
, если истек период ожидания.
release
(
)
¶
Отпустите замок. Это может быть вызвано из любого процесса или поток, а не
только из процесса или поток, которые первоначально приобрели блокировку.
Поведение аналогично поведению в
threading.Lock.release()
, за исключением того, что при
вызове на разблокированной блокировке возникает
ValueError
.
class
multiprocessing.
RLock
¶
Объект рекурсивной блокировки: близкий аналог
threading.RLock
. Рекурсивная блокировка
должна быть разблокирована процессом или поток, получившим ее. Как только
процесс или поток приобрел рекурсивную блокировку, тот же самый процесс
или поток может снова получить ее без блокировки; этот процесс или
поток должны выпускать его один раз в каждый раз, когда он был приобретен.
Обратите внимание, что
RLock
- на самом деле фабричная функция, какой
возвращает сущность
multiprocessing.synchronize.RLock
инициализировал с дефолтом контекст.
RLock
поддерживает протокол
контекстного менеджера
и таким образом может быть используемый в
with
инструкции.
acquire
(
block=True
,
timeout=None
)
¶
Получить блокировку, блокировку или неблокировку.
При вызове с аргументом
block
, имеющим значение
True
, блокировать до
тех пор, пока блокировка не окажется в разблокированном состояние (не
принадлежащем какому-либо процессу или поток), пока блокировка уже не
принадлежит текущему процессу или поток. Текущий процесс или поток
затем получает право собственности на блокировку (если она еще не имеет права
собственности), а уровень рекурсии внутри блокировки увеличивается на единицу,
что приводит к возвращает значение
True
. Обратите внимание, что в
поведении этого первого аргумента существует несколько различий по сравнению с
реализацией
threading.RLock.acquire()
, начиная с имени самого аргумента.
При вызове с аргументом
block
, имеющим значение
False
, не
блокируйте. Если замок был уже приобретен (и таким образом принадлежит) другим
процессом или поток, текущий процесс или поток не берут
собственность, и уровень рекурсии в замке не изменен, приведя к возвращает
значение
False
. Если блокировка находится в разблокированном
состояние, текущий процесс или поток становится владельцем и уровень
рекурсии увеличивается, что приводит к возвращает значение
True
.
Использование и поведение аргумента
timeout
такие же, как и в
Lock.acquire()
.
Обратите внимание, что некоторые из этих поведений
timeout
отличаются от
реализованных поведений в
threading.RLock.acquire()
.
release
(
)
¶
Разблокируйте блокировку, уменьшая уровень рекурсии. Если после уменьшения
уровень рекурсии равен нулю, сбросьте блокировку на разблокированную (не
принадлежащую какому-либо процессу или поток) и если какие-либо другие
процессы или потоки заблокированы в ожидании разблокировки блокировки,
разрешите выполнение только одного из них. Если после уменьшения уровень
рекурсии остается ненулевым, блокировка остается заблокированной и принадлежит
вызывающему процессу или поток.
Только назовите этот метод, когда процесс запроса или поток будут владеть
замком.
AssertionError
поднят, если этот метод называют процесс или поток
кроме владельца или если замок находится в незапертом (ненаходящемся в
собственности) состояние. Обратите внимание, что тип исключения, вызванного в
этой ситуации, отличается от реализованного поведения в
threading.RLock.release()
.
class
multiprocessing.
Semaphore
(
[
value
]
)
¶
Семафорный объект: близкий аналог
threading.Semaphore
.
Существует одиночное отличие от его близкого аналога: первый аргумент его метода
acquire
называется
block
, как это согласуется с
Lock.acquire()
.
Примечание
В Mac OS X
sem_timedwait
не поддерживается, поэтому вызов
acquire()
с тайм-аутом
будет эмулировать поведение этой функции с помощью спящего цикла.
Примечание
Если сигнал SIGINT, сгенерированный
Ctrl-C
, прибудет, в то время как
главный поток заблокирован требованием к
BoundedSemaphore.acquire()
,
Lock.acquire()
,
RLock.acquire()
,
Semaphore.acquire()
,
Condition.acquire()
или
Condition.wait()
тогда, требование будет
немедленно прервано, и
KeyboardInterrupt
будет поднят.
Это отличается от поведения
threading
, где SIGINT будет игнорироваться во
время выполнения эквивалентных блокирующих вызовов.
Примечание
Некоторые функциональные возможности этого пакета требуют функциональной
реализации общего семафора в операционной системе хоста. Без него модуль
multiprocessing.synchronize
будет отключен, и попытки его импорта приведут к появлению
ImportError
. Дополнительные сведения см. в разделе
bpo-3770
.
Разделенные объекты
ctypes
¶
С помощью общей памяти можно создавать общие объекты, которые могут
наследоваться дочерними процессами.
multiprocessing.
Value
(
typecode_or_type
,
*args
,
lock=True
)
¶
Возвращает объект
ctypes
, выделенный из общей памяти. По умолчанию
возвращает значение фактически является синхронизированной оболочкой для
объекта. К самому объекту можно получить доступ через
value
атрибут
Value
.
typecode_or_type
определяет тип объекта возвращенный: это - или тип ctypes или один
символ typecode доброго используемый модулем
array
.
*args
передан конструктору для типа.
Если
lock
равно
True
(по умолчанию), создается новый объект
рекурсивной блокировки для синхронизации доступа к значение. Если
lock
является объектом
Lock
или
RLock
, то это будет используемый для
синхронизации доступа к значение. Если
lock
будет
False
тогда, то
доступ к объекту возвращенный не будет автоматически защищен замком, таким
образом, это не обязательно будет «безопасно от процесса».
Операции как
+=
, которые включают прочитанный и пишут, не атомные. Так
что, если для сущность, вы хотите атомарно увеличить общий значение это
недостаточно, чтобы просто сделать:
counter
.
value
+=
1
Предполагая, что связанная блокировка является рекурсивной (что по умолчанию),
можно сделать:
with
counter
.
get_lock
():
counter
.
value
+=
1
Обратите внимание, что
lock
является только ключевым аргументом.
multiprocessing.
Array
(
typecode_or_type
,
size_or_initializer
,
*
,
lock=True
)
¶
Возвращает массив ctypes, выделенный из общей памяти. По умолчанию возвращает
значение фактически является синхронизированной обёрткой для массива.
typecode_or_type
определяет тип элементов множества возвращенный: это - или тип ctypes
или один символ typecode доброго используемый модулем
array
. Если
size_or_initializer
является целым числом, то он определяет длину массива, и массив будет
первоначально обнулен. Иначе
size_or_initializer
- последовательность, которая является
используемый, чтобы инициализировать множество и чья длина определяет длину
множества.
Если
lock
равно
True
(по умолчанию), создается новый объект
блокировки для синхронизации доступа к значение. Если
lock
является
объектом
Lock
или
RLock
, то это будет используемый для синхронизации
доступа к значение. Если
lock
будет
False
тогда, то доступ к
объекту возвращенный не будет автоматически защищен замком, таким образом, это не
обязательно будет «безопасно от процесса».
Обратите внимание, что
lock
- ключевой только аргумент.
Обратите внимание, что у множества
ctypes.c_char
есть
value
и
raw
атрибуты, которые позволяют использовать его, чтобы сохранить и восстановить
строки.
Модуль
multiprocessing.sharedctypes
¶
Модуль
multiprocessing.sharedctypes
предоставляет функции для выделения объектов
ctypes
из
общей памяти, которые могут быть унаследованы дочерними процессами.
Примечание
Хотя можно сохранить указатель в общей памяти, помните, что это относится к
расположению в адресном пространстве конкретного процесса. Однако указатель,
вероятно, недействителен в контекст второго процесса, и попытка отсоединить
указатель от второго процесса может вызвать сбой.
multiprocessing.sharedctypes.
RawArray
(
typecode_or_type
,
size_or_initializer
)
¶
Возвращает массив ctypes, выделенный из общей памяти.
typecode_or_type
определяет тип элементов множества возвращенный: это - или тип ctypes
или один символ typecode доброго используемый модулем
array
. Если
size_or_initializer
является целым числом, то он определяет длину массива, и массив
будет первоначально обнулен. Иначе
size_or_initializer
- последовательность, которая
является используемый, чтобы инициализировать множество и чья длина определяет
длину множества.
Обратите внимание, что настройка и получение элемента потенциально неатомны -
вместо этого используйте команду
Array()
, чтобы убедиться, что доступ
автоматически синхронизирован с помощью блокировки.
multiprocessing.sharedctypes.
RawValue
(
typecode_or_type
,
*args
)
¶
Возвращает объект ctypes, выделенный из общей памяти.
typecode_or_type
определяет тип объекта возвращенный: это - или тип ctypes или один
символ typecode доброго используемый модулем
array
.
*args
передан конструктору для типа.
Обратите внимание, что настройка и получение значение потенциально неатомны -
вместо этого используйте
Value()
, чтобы убедиться, что доступ автоматически
синхронизирован с помощью блокировки.
Обратите внимание, что массив
ctypes.c_char
имеет
value
и
raw
атрибуты, которые позволяют использовать его для хранения и извлечения
строки - см. документацию для
ctypes
.
multiprocessing.sharedctypes.
Array
(
typecode_or_type
,
size_or_initializer
,
*
,
lock=True
)
¶
То же как
RawArray()
за исключением того, что в зависимости от значение
lock
безопасная от процесса обертка синхронизации может быть возвращенный
вместо сырья ctypes множество.
Если
lock
равно
True
(по умолчанию), создается новый объект
блокировки для синхронизации доступа к значение. Если
lock
является
объектом
Lock
или
RLock
, то это будет используемый для синхронизации
доступа к значение. Если
lock
будет
False
тогда, то доступ к
объекту возвращенный не будет автоматически защищен замком, таким образом, это не
обязательно будет «безопасно от процесса».
Обратите внимание, что
lock
является толко ключевым аргументом.
multiprocessing.sharedctypes.
Value
(
typecode_or_type
,
*args
,
lock=True
)
¶
То же как
RawValue()
за исключением того, что в зависимости от значение
lock
безопасная от процесса обертка синхронизации может быть возвращенный
вместо сырья ctypes объект.
Если
lock
равно
True
(по умолчанию), создается новый объект
блокировки для синхронизации доступа к значение. Если
lock
является
объектом
Lock
или
RLock
, то это будет используемый для синхронизации
доступа к значение. Если
lock
будет
False
тогда, то доступ к
объекту возвращенный не будет автоматически защищен замком, таким образом, это не
обязательно будет «безопасно от процесса».
Обратите внимание, что
lock
является только ключевым аргументом.
multiprocessing.sharedctypes.
copy
(
obj
)
¶
Возвращает объект ctypes, выделенный из общей памяти, который является копией
объекта ctypes
obj
.
multiprocessing.sharedctypes.
synchronized
(
obj
[
,
lock
]
)
¶
Возвращает безопасный для процесса объект-обертка для объекта ctypes, который
использует
lock
для синхронизации доступа. Если
lock
имеет
значение
None
(по умолчанию), то объект
multiprocessing.RLock
создается
автоматически.
Синхронизированная обертка будет иметь два метода в дополнение к методам
обертываемого объекта:
get_obj()
возвращает обертываемый объект и
get_lock()
возвращает блокируемый объект используемый для синхронизации.
Обратите внимание, что доступ к объекту ctypes через оболочку может быть намного
медленнее, чем доступ к объекту raw ctypes.
Изменено в версии 3.5:
Синхронизированные объекты поддерживают протокол
менеджера контекста
.
В приведенной ниже таблице сравнивается синтаксис создания общих объектов ctypes
из общей памяти с синтаксисом обычных ctypes. (В таблице
MyStruct
представлена некоторая подкласс
ctypes.Structure
.
ctypes
sharedctypes используя тип
sharedctypes используя typecode
c_double(2.4)
RawValue(c_double, 2.4)
RawValue(„d“, 2.4)
MyStruct(4, 6)
RawValue(MyStruct, 4, 6)
(c_short * 7)()
RawArray(c_short, 7)
RawArray(„h“, 7)
(c_int * 3)(9, 2, 8)
RawArray(c_int, (9, 2, 8))
RawArray(„i“, (9, 2, 8))
Ниже приведен пример, когда ряд объектов ctypes изменяется дочерним процессом:
from
multiprocessing
import
Process
,
Lock
from
multiprocessing.sharedctypes
import
Value
,
Array
from
ctypes
import
Structure
,
c_double
class
Point
(
Structure
):
_fields_
=
[(
'x'
,
c_double
),
(
'y'
,
c_double
)]
def
modify
(
n
,
x
,
s
,
A
):
n
.
value
**=
2
x
.
value
**=
2
s
.
value
=
s
.
value
.
upper
()
for
a
in
A
:
a
.
x
**=
2
a
.
y
**=
2
if
__name__
==
'__main__'
:
lock
=
Lock
()
n
=
Value
(
'i'
,
7
)
x
=
Value
(
c_double
,
1.0
/
3.0
,
lock
=
False
)
s
=
Array
(
'c'
,
b
'hello world'
,
lock
=
lock
)
A
=
Array
(
Point
,
[(
1.875
,
-
6.25
),
(
-
5.75
,
2.0
),
(
2.375
,
9.5
)],
lock
=
lock
)
p
=
Process
(
target
=
modify
,
args
=
(
n
,
x
,
s
,
A
))
p
.
start
()
p
.
join
()
print
(
n
.
value
)
print
(
x
.
value
)
print
(
s
.
value
)
print
([(
a
.
x
,
a
.
y
)
for
a
in
A
])
Результаты напечатаны:
49
0.1111111111111111
HELLO WORLD
[(3.515625, 39.0625), (33.0625, 4.0), (5.640625, 90.25)]
Менеджеры
¶
Менеджеры предоставляют способ создания данных, которые могут совместно
использоваться различными процессами, включая совместное использование по сети
между процессами, работающими на разных машинах. Объект-менеджер управляет
серверным процессом, который управляет
shared objects
. Другие процессы могут
обращаться к общим объектам с помощью прокси.
multiprocessing.
Manager
(
)
¶
Возвращает начатый объект
SyncManager
, который может
быть используемый для
разделения объектов между процессами. Объект менеджера возвращенный соответствует
порожденному дочернему процессу и имеет методы, которые создадут общие объекты и
соответствующие возвращаемое прокси.
Процессы менеджера будут остановлены сразу после сбора мусора или завершения
родительского процесса. Классы менеджера определяются в модуле
multiprocessing.managers
:
class
multiprocessing.managers.
BaseManager
(
[
address
[
,
authkey
]
]
)
¶
Создайте объект BaseManager.
После создания необходимо вызвать
start()
или
get_server().serve_forever()
, чтобы
гарантировать, что объект менеджера ссылается на запущенный процесс менеджера.
address
- адрес, по которому процесс менеджера прослушивает новые
подключения. Если
address
None
, то выбирается произвольная.
authkey
- ключ идентификации, который будет используемый, чтобы проверить
законность поступающих связей с процессом сервера. Если
authkey
-
None
тогда,
current_process().authkey
- используемый. В противном случае
authkey
является используемый и должен быть байтом строка.
start
(
[
initializer
[
,
initargs
]
]
)
¶
Начните подпроцессы, чтобы начать менеджера. Если
initializer
не является
None
, то подпроцессы вызовет
initializer(*initargs)
при запуске.
get_server
(
)
¶
Возвращает объект
Server
, представляющий фактический сервер под управлением
менеджера. Объект
Server
поддерживает метод
serve_forever()
:
>>>
>>>
from
multiprocessing.managers
import
BaseManager
>>>
manager
=
BaseManager
(
address
=
(
''
,
50000
),
authkey
=
b
'abc'
)
>>>
server
=
manager
.
get_server
()
>>>
server
.
serve_forever
()
Server
дополнительно содержит
address
атрибут.
connect
(
)
¶
Подключить объект локального менеджера к процессу удаленного менеджера:
>>>
>>>
from
multiprocessing.managers
import
BaseManager
>>>
m
=
BaseManager
(
address
=
(
'127.0.0.1'
,
50000
),
authkey
=
b
'abc'
)
>>>
m
.
connect
()
shutdown
(
)
¶
Остановить процесс используемый менеджером. Это только доступно, если
start()
был используемый, чтобы начать процесс сервера.
Это можно вызвать несколько раз.
register
(
typeid
[
,
callable
[
,
proxytype
[
,
exposed
[
,
method_to_typeid
[
,
create_method
]
]
]
]
]
)
¶
classmethod, который может быть используемый для регистрации типа или подлежащий
выкупу с классом менеджера.
typeid
- «идентификатор типа», который является используемый, чтобы
определить особый тип общего объекта. Это должно быть строка.
callable
является вызываемым используемый для создания объектов для этого
идентификатора типа. Если диспетчер сущность будет подключен к серверу с
помощью метода
connect()
или если аргумент
create_method
имеет значение
False
, его можно оставить как
None
.
proxytype
является подкласс
BaseProxy
, который используемый для создания
прокси для общих объектов с этим
typeid
. Если
None
, то класс прокси
создается автоматически.
exposed
- используемый, чтобы определить последовательность вызова метода,
которые прокси для этого typeid нужно разрешить доступу, используя
BaseProxy._callmethod()
. (Если
exposed
-
None
тогда,
proxytype._exposed_
- используемый
вместо этого, если он существует.) в случае, если не указан список разоблаченных
объектов, будут доступны все «публичные методы» общего объекта. (Здесь «метод
публичный» означает любой атрибут, у которого есть метод
__call__()
и чьё
имя не начинается с
'_'
.)
method_to_typeid
- отображение используемый, чтобы определить тип возвращает тех
выставленных методов, которые должны возвращает прокси. Это наносит на
карту названия метода к typeid строки. (Если
method_to_typeid
-
None
тогда,
proxytype._method_to_typeid_
- используемый вместо этого, если он существует.) Если
вызов метода не будет ключом этого отображения или если отображение будет
None
тогда объект, то возвращенный методом будет скопирован значение.
create_method
определяет, должен ли метод быть создан с именем
typeid
,
который может быть используемый, чтобы сказать процессу сервера создавать новый
общий объект и возвращает прокси для него. По умолчанию это значение равно
True
.
BaseManager
сущности также имеют одно свойство только для чтения:
address
¶
Адрес, используемый менеджером.
Изменено в версии 3.3:
Объекты менеджера поддерживают протокол управления контекст - см. раздел
Типы менеджера контекста
.
__enter__()
запускает процесс сервера
(если он еще не запущен), а
затем возвращает объект диспетчера.
__exit__()
вызовы
shutdown()
.
В предыдущих версиях
__enter__()
не запускал серверный процесс диспетчера, если
он еще не был запущен.
class
multiprocessing.managers.
SyncManager
¶
Подкласс
BaseManager
, который может быть используемый для синхронизации
процессов. Объекты этого типа возвращенный
multiprocessing.Manager()
.
Его методы обычно создают и возвращает
Прокси объекты
для многих типы данных
используемый, которые будут синхронизированы через процессы. Это, в частности,
включает общие списки и словари.
Barrier
(
parties
[
,
action
[
,
timeout
]
]
)
¶
Создание общего объекта
threading.Barrier
и возвращает прокси для него.
Добавлено в версии 3.3.
BoundedSemaphore
(
[
value
]
)
¶
Создание общего объекта
threading.BoundedSemaphore
и возвращает прокси для него.
Condition
(
[
lock
]
)
¶
Создание общего объекта
threading.Condition
и возвращает прокси для него.
Если задано значение
lock
, то оно должно быть прокси для объекта
threading.Lock
или
threading.RLock
.
Изменено в версии 3.3:
Добавлен метод
wait_for()
.
Event
(
)
¶
Создание общего объекта
threading.Event
и возвращает прокси для него.
Lock
(
)
¶
Создание общего объекта
threading.Lock
и возвращает прокси для него.
Namespace
(
)
¶
Создание общего объекта
Namespace
и возвращает прокси для него.
Queue
(
[
maxsize
]
)
¶
Создание общего объекта
queue.Queue
и возвращает прокси для него.
RLock
(
)
¶
Создание общего объекта
threading.RLock
и возвращает прокси для него.
Semaphore
(
[
value
]
)
¶
Создание общего объекта
threading.Semaphore
и возвращает прокси для него.
Array
(
typecode
,
sequence
)
¶
Создайте массив и возвращает прокси-сервер для него.
Value
(
typecode
,
value
)
¶
Создайте объект с возможностью записи
value
атрибут и возвращает
прокси для него.
dict
(
)
¶
dict
(
mapping
)
dict
(
sequence
)
Создание общего объекта
dict
и возвращает прокси для него.
list
(
)
¶
list
(
sequence
)
Создание общего объекта
list
и возвращает прокси для него.
Изменено в версии 3.6:
Общие объекты могут быть вложены. Например, объект общего контейнера, такой как
общий список, может содержать другие общие объекты, которые будут управляться и
синхронизироваться
SyncManager
.
class
multiprocessing.managers.
Namespace
¶
Тип, который может регистрироваться в
SyncManager
.
Объект пространства имен не имеет публичных методов, но содержит записываемые
атрибуты. Его представление показывает значения его атрибутов.
Однако при использовании прокси для объекта пространства имен атрибут,
начинающийся с
'_'
, будет атрибут прокси, а не атрибут ссылки:
>>>
>>>
manager
=
multiprocessing
.
Manager
()
>>>
Global
=
manager
.
Namespace
()
>>>
Global
.
x
=
10
>>>
Global
.
y
=
'hello'
>>>
Global
.
_z
=
12.3
# это атрибут прокси
>>>
print
(
Global
)
Namespace(x=10, y='hello')
Настраиваемые менеджеры
¶
Для создания собственного менеджера создается подкласс
BaseManager
и используется
классметод
register()
для регистрации новых типов или вызываемых объектов в
классе менеджера. Например:
from
multiprocessing.managers
import
BaseManager
class
MathsClass
:
def
add
(
self
,
x
,
y
):
return
x
+
y
def
mul
(
self
,
x
,
y
):
return
x
*
y
class
MyManager
(
BaseManager
):
pass
MyManager
.
register
(
'Maths'
,
MathsClass
)
if
__name__
==
'__main__'
:
with
MyManager
()
as
manager
:
maths
=
manager
.
Maths
()
print
(
maths
.
add
(
4
,
3
))
# prints 7
print
(
maths
.
mul
(
7
,
8
))
# prints 56
Использование удаленного менеджера
¶
Можно запускать сервер менеджера на одной машине и использовать его клиентами с
других машин (при условии, что соответствующие брандмауэры разрешают это).
Выполнение следующих команд создает сервер для одной общей очереди, к которой
могут иметь доступ удаленные клиенты:
>>>
>>>
from
multiprocessing.managers
import
BaseManager
>>>
from
queue
import
Queue
>>>
queue
=
Queue
()
>>>
class
QueueManager
(
BaseManager
):
pass
>>>
QueueManager
.
register
(
'get_queue'
,
callable
=
lambda
:
queue
)
>>>
m
=
QueueManager
(
address
=
(
''
,
50000
),
authkey
=
b
'abracadabra'
)
>>>
s
=
m
.
get_server
()
>>>
s
.
serve_forever
()
Один клиент может получить доступ к серверу следующим образом:
>>>
>>>
from
multiprocessing.managers
import
BaseManager
>>>
class
QueueManager
(
BaseManager
):
pass
>>>
QueueManager
.
register
(
'get_queue'
)
>>>
m
=
QueueManager
(
address
=
(
'foo.bar.org'
,
50000
),
authkey
=
b
'abracadabra'
)
>>>
m
.
connect
()
>>>
queue
=
m
.
get_queue
()
>>>
queue
.
put
(
'hello'
)
Его также может использовать другой клиент:
>>>
>>>
from
multiprocessing.managers
import
BaseManager
>>>
class
QueueManager
(
BaseManager
):
pass
>>>
QueueManager
.
register
(
'get_queue'
)
>>>
m
=
QueueManager
(
address
=
(
'foo.bar.org'
,
50000
),
authkey
=
b
'abracadabra'
)
>>>
m
.
connect
()
>>>
queue
=
m
.
get_queue
()
>>>
queue
.
get
()
'hello'
Локальные процессы также могут обращаться к этой очереди, используя код
сверху на клиенте для удаленного доступа к ней:
>>>
>>>
from
multiprocessing
import
Process
,
Queue
>>>
from
multiprocessing.managers
import
BaseManager
>>>
class
Worker
(
Process
):
...
def
__init__
(
self
,
q
):
...
self
.
q
=
q
...
super
(
Worker
,
self
)
.
__init__
()
...
def
run
(
self
):
...
self
.
q
.
put
(
'local hello'
)
...
>>>
queue
=
Queue
()
>>>
w
=
Worker
(
queue
)
>>>
w
.
start
()
>>>
class
QueueManager
(
BaseManager
):
pass
...
>>>
QueueManager
.
register
(
'get_queue'
,
callable
=
lambda
:
queue
)
>>>
m
=
QueueManager
(
address
=
(
''
,
50000
),
authkey
=
b
'abracadabra'
)
>>>
s
=
m
.
get_server
()
>>>
s
.
serve_forever
()
Прокси объекты
¶
Прокси - объект, какой
относится
к общему объекту, который живет (по-
видимому), в другом процессе. Говорят, что общий объект является
ссылкой
прокси. Несколько прокси-объектов могут иметь один и тот же ссылочный объект.
Прокси-объект содержат методы, которые вызывают соответствующие методы его ссылки
(хотя не каждый метод ссылки обязательно будет доступен через прокси). Таким
образом, прокси может быть используемый так же, как его референт:
>>>
>>>
from
multiprocessing
import
Manager
>>>
manager
=
Manager
()
>>>
l
=
manager
.
list
([
i
*
i
for
i
in
range
(
10
)])
>>>
print
(
l
)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>>
print
(
repr
(
l
))
<ListProxy object, typeid 'list' at 0x...>
>>>
l
[
4
]
16
>>>
l
[
2
:
5
]
[4, 9, 16]
Заметьте, что применение
str()
прокси будет возвращает представление
референта, тогда как применение
repr()
будет возвращает представление
прокси.
Важной особенностью прокси-объектов является то, что они могут быть переданы
между процессами. Таким образом, референт может содержать
Прокси объекты
. Это
разрешает вложение этих управляемых списков, словари и другого
Прокси объекты
:
>>>
>>>
a
=
manager
.
list
()
>>>
b
=
manager
.
list
()
>>>
a
.
append
(
b
)
# ссылка a теперь содержит ссылку b
>>>
print
(
a
,
b
)
[<ListProxy object, typeid 'list' at ...>] []
>>>
b
.
append
(
'hello'
)
>>>
print
(
a
[
0
],
b
)
['hello'] ['hello']
Аналогично, прокси словарь и списка могут быть вложены друг в друга:
>>>
>>>
l_outer
=
manager
.
list
([
manager
.
dict
()
for
i
in
range
(
2
)
])
>>>
d_first_inner
=
l_outer
[
0
]
>>>
d_first_inner
[
'a'
]
=
1
>>>
d_first_inner
[
'b'
]
=
2
>>>
l_outer
[
1
][
'c'
]
=
3
>>>
l_outer
[
1
][
'z'
]
=
26
>>>
print
(
l_outer
[
0
])
{'a': 1, 'b': 2}
>>>
print
(
l_outer
[
1
])
{'c': 3, 'z': 26}
Если стандартные (не прокси)
list
или
dict
объекты содержатся в
ссылке, изменения этих изменяемых значения не будут распространяться через
менеджер, поскольку прокси не может знать, когда изменятся содержащиеся в них
значения. Однако хранение значение в контейнерном прокси (который
вызывает
__setitem__
на объекте по доверенности) действительно размножается
через менеджера и так эффективно изменить такой предмет, можно было повторно
назначить измененный значение контейнерному прокси:
# создать список прокси и добавить изменяемый объект (словарь)
lproxy
=
manager
.
list
()
lproxy
.
append
({})
# теперь изменяемый словарь
d
=
lproxy
[
0
]
d
[
'a'
]
=
1
d
[
'b'
]
=
2
# на этом этапе изменения d еще не синхронизируются, но при обновлении словаря
# прокси уведомляется об изменении
lproxy
[
0
]
=
d
Этот подход, возможно, менее удобен, чем использование вложенных
Прокси объекты
в
большинстве случаев использования, но также демонстрирует уровень управления
синхронизацией.
Примечание
Прокси-типы в
multiprocessing
не поддерживают сравнения по значение. Итак, для
сущность у нас есть:
>>>
>>>
manager
.
list
([
1
,
2
,
3
])
==
[
1
,
2
,
3
]
False
Вместо этого следует использовать копию ссылки при проведении сравнений.
class
multiprocessing.managers.
BaseProxy
¶
Объекты по доверенности - сущности подклассы
BaseProxy
.
_callmethod
(
methodname
[
,
args
[
,
kwds
]
]
)
¶
Вызов и возвращает результата метода ссылки прокси.
Если
proxy
- прокси, ссылочным элементом которого является
obj
, то
выражение:
proxy
.
_callmethod
(
methodname
,
args
,
kwds
)
вычислит выражение:
getattr
(
obj
,
methodname
)(
*
args
,
**
kwds
)
в процессе менеджере.
возвращенный значение будет копией результата вызова или прокси для нового
общего объекта - см. документацию для аргумента
method_to_typeid
BaseManager.register()
.
Если в результате вызова возникает исключение, то вызов повторно инициируется
функцией
_callmethod()
. Если в процессе менеджера возникает другое исключение, оно
преобразуется в исключение
RemoteError
и инициируется
_callmethod()
.
Обратите внимание, в частности, на то, что исключение будет создано, если
methodname
не было
exposed
.
Пример использования
_callmethod()
:
>>>
>>>
l
=
manager
.
list
(
range
(
10
))
>>>
l
.
_callmethod
(
'__len__'
)
10
>>>
l
.
_callmethod
(
'__getitem__'
,
(
slice
(
2
,
7
),))
# equivalent to l[2:7]
[2, 3, 4, 5, 6]
>>>
l
.
_callmethod
(
'__getitem__'
,
(
20
,))
# equivalent to l[20]
Traceback (most recent call last):
...
IndexError
:
list index out of range
_getvalue
(
)
¶
Возвращает копию референта.
Если референт не может быть выбран, это вызовет исключение.
__repr__
(
)
¶
Возвращает представление прокси-объекта.
__str__
(
)
¶
Возвращает представление референта.
Очистка
¶
Объект по доверенности использует weakref колбэк так, чтобы, когда это
собрало мусор, он вычеркнул из списка себя от менеджера, который владеет его
референтом.
Общий объект удаляется из процесса диспетчера, если на него больше не ссылается
ни один прокси.
Процессные пулы
¶
Можно создать пул процессов, который будет выполнять задачи, переданные ему с
классом
Pool
.
class
multiprocessing.pool.
Pool
(
[
processes
[
,
initializer
[
,
initargs
[
,
maxtasksperchild
[
,
context
]
]
]
]
]
)
¶
Объект пула процессов, который управляет пулом рабочих процессов, в который
могут отправляться задания. Он поддерживает асинхронные результаты с тайм-аутами
и колбэки и имеет параллельную реализацию карты.
processes
- количество используемых рабочих процессов. Если
processes
None
, то число возвращенный по
os.cpu_count()
равно используемый.
Если
initializer
не является
None
, то каждый рабочий процесс будет
вызывать
initializer(*initargs)
при запуске.
maxtasksperchild
- количество задач, которые рабочий процесс может выполнить до
выхода и замены новым рабочим процессом для освобождения неиспользуемых
ресурсов. Дефолт
maxtasksperchild
-
None
, что означает процессы рабочего,
будет жить пока бассейн.
context
может быть используемый, чтобы определить контекст используемый для
старта процессов рабочего. Обычно пул создается с помощью функции
multiprocessing.Pool()
или метода
Pool()
объекта контекст. В обоих случаях
context
устанавливается соответствующим образом.
Следует отметить, что методы объекта пула должны вызываться только процессом,
создавшим пул.
Предупреждение
multiprocessing.pool
объекты имеют внутренние ресурсы, которыми необходимо правильно
управлять (как и любой другой ресурс), используя пул в качестве менеджера
контекст или вызывая
close()
и
terminate()
вручную. Неспособность сделать
это может привести к зависанию процесса при завершении.
Обратите внимание, что это
не верно
, чтобы полагаться на сборщик мусора,
чтобы уничтожить пул, так как CPython не гарантирует, что финализатор пула
будет вызван (см.
object.__del__()
для получения дополнительной информации).
Добавлено в версии 3.2:
maxtasksperchild
Добавлено в версии 3.4:
context
Примечание
Рабочие процессы внутри
Pool
обычно работают в течение всей
продолжительности рабочей очереди пула. Частый шаблон, встречающийся в других
системах (таких как Apache, mod_wsgi и т.д.) для освобождения ресурсов,
находящихся в распоряжении работников, заключается в том, чтобы позволить
работнику в пуле выполнить только определенный объем работы перед выходом,
очисткой и новым процессом, который должен заменить старый. Аргумент
maxtasksperchild
Pool
предоставляет эту возможность конечному пользователю.
apply
(
func
[
,
args
[
,
kwds
]
]
)
¶
Вызовите
func
с аргументами
args
и ключевой аргументы
kwds
. Он блокируется до тех пор, пока результат не будет готов. Учитывая
эти блоки,
apply_async()
лучше подходит для выполнения работы параллельно. Кроме
того,
func
выполняется только в одном из работников пула.
apply_async
(
func
[
,
args
[
,
kwds
[
,
callback
[
,
error_callback
]
]
]
]
)
¶
Вариант метода
apply()
, который возвращает
объект
AsyncResult
.
Если задан параметр
callback
, то он должен быть вызываемым и принимать один
аргумент. То, когда результат становится готовым
callback
, применено к нему,
это - то, если неудавшееся требование, в этом случае
error_callback
не применен
вместо этого.
Если задан параметр
error_callback
, то он должен быть вызываемым и принимать один
аргумент. Если целевая функция терпит неудачу, то
error_callback
называют за
исключением сущность.
Обратные вызовы должны быть завершены немедленно, поскольку в противном случае
поток, обрабатывающая результаты, будет заблокирована.
map
(
func
,
iterable
[
,
chunksize
]
)
¶
Параллельный эквивалент встроенной функции
map()
(однако он поддерживает
только один аргумент
iterable
для нескольких итерабелей см.
starmap()
). Он
блокируется до тех пор, пока результат не будет готов.
Этот метод разбивает итабль на несколько чанки, которые он передает в пул
процессов как отдельные задачи. (Приблизительный) размер этих чанки можно
задать, установив для параметра
chunksize
положительное целое число.
Обратите внимание, что это может привести к интенсивному использованию памяти
для очень длинных итераблей. Рассмотрите возможность использования
imap()
или
imap_unordered()
с явным параметром
chunksize
для повышения эффективности.
map_async
(
func
,
iterable
[
,
chunksize
[
,
callback
[
,
error_callback
]
]
]
)
¶
Вариант метода
map()
, который возвращает объект
AsyncResult
.
Если задан параметр
callback
, то он должен быть вызываемым и принимать один
аргумент. То, когда результат становится готовым
callback
, применено к нему,
это - то, если неудавшееся требование, в этом случае
error_callback
не применен
вместо этого.
Если задан параметр
error_callback
, то он должен быть вызываемым и принимать один
аргумент. Если целевая функция терпит неудачу, то
error_callback
называют за
исключением сущность.
Обратные вызовы должны быть завершены немедленно, поскольку в противном случае
поток, обрабатывающая результаты, будет заблокирована.
imap
(
func
,
iterable
[
,
chunksize
]
)
¶
Более ленивый вариант
map()
.
Аргумент
chunksize
совпадает с аргументом используемый методом
map()
.
Очень долго iterables использование большого значение для
chunksize
может
заставить работу закончить
гораздо
быстрее, чем использование дефолта
значение
1
.
Также если
chunksize
является
1
, то метод
next()
итератора
возвращенный методом
imap()
имеет необязательный параметр
timeout
:
next(timeout)
поднимет
multiprocessing.TimeoutError
, если результат не
может быть возвращенный в течение
timeout
секунд.
imap_unordered
(
func
,
iterable
[
,
chunksize
]
)
¶
То же как
imap()
за исключением того, что заказ результатов возвращенный
iterator нужно считать произвольным. (Только при наличии только одного рабочего
процесса порядок гарантирован как «правильный».
starmap
(
func
,
iterable
[
,
chunksize
]
)
¶
Как
map()
за исключением того, что элементы
iterable
, как ожидают, будут
iterables, которые распакованы как аргументы.
Следовательно
iterable
[(1,2),
(3,
4)]
приводит к
[func(1,2),
func(3,4)]
.
Добавлено в версии 3.3.
starmap_async
(
func
,
iterable
[
,
chunksize
[
,
callback
[
,
error_callback
]
]
]
)
¶
Комбинация
starmap()
и
map_async()
, которая итерирует по
iterable
итераблей
и вызывает
func
с итераблями распакованными. Возвращает объект
результата.
Добавлено в версии 3.3.
close
(
)
¶
Запрещает отправку дополнительных задач в пул. После завершения всех задач
рабочие процессы завершаются.
terminate
(
)
¶
Немедленная остановка рабочих процессов без завершения незавершенной работы. То,
когда объект бассейна - мусор, собралось,
terminate()
немедленно назовут.
join
(
)
¶
Дождитесь завершения рабочих процессов. Перед использованием
close()
необходимо вызвать
terminate()
или
join()
.
class
multiprocessing.pool.
AsyncResult
¶
Класс результата возвращенный по
Pool.apply_async()
и
Pool.map_async()
.
get
(
[
timeout
]
)
¶
Возвращает результат при его поступлении. Если
timeout
не является
None
и результат не поступает в течение
timeout
секунд, то
multiprocessing.TimeoutError
поднимается. Если удаленное требование подняло
исключение тогда, что исключение будет повторно поднято
get()
.
wait
(
[
timeout
]
)
¶
Подождите, пока результат будет доступен, или до истечения
timeout
секунд.
ready
(
)
¶
Возвращает, завершен ли вызов.
successful
(
)
¶
Возвращает, выполнен ли вызов без возникновения исключения. Поднимет
ValueError
, если результат не готов.
В следующем примере показано использование пула:
from
multiprocessing
import
Pool
import
time
def
f
(
x
):
return
x
*
x
if
__name__
==
'__main__'
:
with
Pool
(
processes
=
4
)
as
pool
:
# запустить 4 процесса воркера
result
=
pool
.
apply_async
(
f
,
(
10
,))
# асинхронно вычислить "f(10)" в одном процессе
print
(
result
.
get
(
timeout
=
1
))
# печатает "100", если только ваш компьютер не работает *очень* медленно
print
(
pool
.
map
(
f
,
range
(
10
)))
# печать "[0, 1, 4,..., 81]"
it
=
pool
.
imap
(
f
,
range
(
10
))
print
(
next
(
it
))
# печать "0"
print
(
next
(
it
))
# печать "1"
print
(
it
.
next
(
timeout
=
1
))
# печать "4" если ваш компьютер не *очень* медленный
result
=
pool
.
apply_async
(
time
.
sleep
,
(
10
,))
print
(
result
.
get
(
timeout
=
1
))
# поднять multiprocessing.TimeoutError
Слушатели и клиенты
¶
Обычно сообщение, проходящее между процессами, сделано, используя очереди, или
при помощи
Connection
возражает возвращенный
Pipe()
.
Однако модуль
multiprocessing.connection
обеспечивает некоторую гибкость. Он в основном дает
высокоуровневый ориентированный на сообщения API для работы с сокеты или
Windows с именем пайпы. У этого также есть поддержка
digest authentication
, используя
модуль
hmac
, и опроса многочисленных связей одновременно.
multiprocessing.connection.
deliver_challenge
(
connection
,
authkey
)
¶
Отправка случайно сгенерированного сообщения на другой конец соединения и
ожидание ответа.
Если ответ соответствует дайджесту сообщения с использованием клавиши
authkey
, то приветственное сообщение отправляется на другой конец
соединения. В противном случае поднимается
AuthenticationError
.
multiprocessing.connection.
answer_challenge
(
connection
,
authkey
)
¶
Получение сообщения, вычисление дайджеста сообщения с использованием
authkey
в качестве ключа, а затем отправка дайджеста обратно.
Если приветственное сообщение не получено, возникает сообщение
AuthenticationError
.
multiprocessing.connection.
Client
(
address
[
,
family
[
,
authkey
]
]
)
¶
Попытка установить соединение с прослушивателем, который использует адрес
address
, возвращая
Connection
.
Тип соединения определяется аргументом
family
, но обычно его можно
опустить, поскольку его обычно можно вывести из формата
address
. (См.
Форматы адреса
)
Если
authkey
задан, а не None, он должен быть байтом строка и
будет используемый в качестве секретного ключа для вызова аутентификации на
основе HMAC. Аутентификация не выполняется, если
authkey
является
None.
AuthenticationError
возникает в случае сбоя аутентификации. См.
Ключи аутентификации
.
class
multiprocessing.connection.
Listener
(
[
address
[
,
family
[
,
backlog
[
,
authkey
]
]
]
]
)
¶
Обертка для связанной сокет или Windows с именем пайп, которая
«слушает» подключения.
address
- адрес, который должен быть используемый связанным сокет или
именованным пайп объекта прослушивателя.
Примечание
Если адрес „0.0.0.0“ будет используемый, то адрес не будет соединяемой конечной
точкой на Windows. Если требуется соединяемая конечная точка, следует
использовать „127.0.0.1“.
family
- тип используемого сокет (или именованного пайп). Это
может быть один из строки
'AF_INET'
(для TCP сокет),
'AF_UNIX'
(для домена Unix сокет) или
'AF_PIPE'
(для Windows с именем
пайп). Из них только первый гарантированно доступен. Если
family
None
, то семейство выводится из формата
address
. Если
address
также является
None
, то выбирается значение по умолчанию. Это семейство по
умолчанию считается самым быстрым из доступных. См.
Форматы адреса
. Обратите
внимание, что если
family
является
'AF_UNIX'
и адрес
None
, то
сокет будет создан в частном временном каталоге, созданном с помощью
tempfile.mkstemp()
.
Если объект прослушивателя использует сокет, то
backlog
(по умолчанию
1) передается методу
listen()
сокет после его привязки.
Если
authkey
задан, а не None, он должен быть байтом строка и
будет используемый в качестве секретного ключа для вызова аутентификации на
основе HMAC. Аутентификация не выполняется, если
authkey
является
None.
AuthenticationError
возникает в случае сбоя аутентификации. См.
Ключи аутентификации
.
accept
(
)
¶
Принять подключение на связанном сокете или именованный пайп объекта
слушателя и возвращает объект
Connection
. Если идентификация предпринята и
терпит неудачу, то поднимается
AuthenticationError
.
close
(
)
¶
Закрыть связанный сокет или именованный пайп объекта слушателя. Это
вызывается автоматически при сборе мусора прослушивателя. Однако желательно
называть его явно.
Объекты прослушивателя имеют следующие свойства только для чтения:
address
¶
Адрес, используемый объектом Listener.
last_accepted
¶
Адрес, с которого пришло последнее принятое соединение. Если это недоступно, то
это
None
.
Добавлено в версии 3.3:
Объекты прослушивателя теперь поддерживают протокол управления контекст - см.
раздел
Типы менеджера контекста
.
__enter__()
возвращает объект прослушивателя, а
__exit__()
вызывает
close()
.
multiprocessing.connection.
wait
(
object_list
,
timeout=None
)
¶
Подождите, пока объект в
object_list
будет готов. Возвращает список тех объектов
в
object_list
, которые готовы. Если
timeout
является float, то вызов
блокируется максимум на столько секунд. Если
timeout
будет
None
тогда, то он заблокирует в течение неограниченного периода. Отрицательное время
ожидания эквивалентно нулевому времени ожидания.
Как для Unix, так и для Windows объект может отображаться в
object_list
, если это
так
читаемый объект
Connection
;
подключенный и читаемый объект
socket.socket
; или
sentinel
атрибут объекта
Process
.
Соединение или объект сокет готов, когда имеются данные, доступные для
чтения из него, или другой конец закрыт.
Unix
:
wait(object_list,
timeout)
почти эквивалентный
select.select(object_list,
[],
[],
timeout)
. Разница в том, что,
если
select.select()
прерывается сигналом, он может поднять
OSError
с числом
ошибок
EINTR
, тогда как
wait()
не будет.
Windows
: Элемент в
object_list
должен или быть целочисленным обработчиком, который ожидает (waitable)
(согласно определению используемый документацией функции Win32
WaitForMultipleObjects()
), или это может быть объект с методом
fileno()
, с каким возвращает ручка сокет или пайп обращаются. (Обратите
внимание, что дескрипторы пайпа и сокет
не
являются дескрипторами ожидания.
Добавлено в версии 3.3.
Примеры
Следующий код сервера создает слушателя, который использует
'secret
password'
в
качестве ключа идентификации. Затем он ожидает подключения и передает некоторые
данные клиенту:
from
multiprocessing.connection
import
Listener
from
array
import
array
address
=
(
'localhost'
,
6000
)
# семейство выведено как 'AF_INET'
with
Listener
(
address
,
authkey
=
b
'secret password'
)
as
listener
:
with
listener
.
accept
()
as
conn
:
print
(
'connection accepted from'
,
listener
.
last_accepted
)
conn
.
send
([
2.25
,
None
,
'junk'
,
float
])
conn
.
send_bytes
(
b
'hello'
)
conn
.
send_bytes
(
array
(
'i'
,
[
42
,
1729
]))
Следующая код подключается к серверу и получает некоторые данные от
сервера:
from
multiprocessing.connection
import
Client
from
array
import
array
address
=
(
'localhost'
,
6000
)
with
Client
(
address
,
authkey
=
b
'secret password'
)
as
conn
:
print
(
conn
.
recv
())
# => [2.25, None, 'junk', float]
print
(
conn
.
recv_bytes
())
# => 'hello'
arr
=
array
(
'i'
,
[
0
,
0
,
0
,
0
,
0
])
print
(
conn
.
recv_bytes_into
(
arr
))
# => 8
print
(
arr
)
# => array('i', [42, 1729, 0, 0, 0])
Следующая код использует
wait()
для ожидания сообщений от
нескольких процессов одновременно:
import
time
,
random
from
multiprocessing
import
Process
,
Pipe
,
current_process
from
multiprocessing.connection
import
wait
def
foo
(
w
):
for
i
in
range
(
10
):
w
.
send
((
i
,
current_process
()
.
name
))
w
.
close
()
if
__name__
==
'__main__'
:
readers
=
[]
for
i
in
range
(
4
):
r
,
w
=
Pipe
(
duplex
=
False
)
readers
.
append
(
r
)
p
=
Process
(
target
=
foo
,
args
=
(
w
,))
p
.
start
()
# Мы закрываем записываемый конец пайп, чтобы убедиться, что p является
# единственным процессом, который владеет дескриптором для него. Это гарантирует,
# что когда p закроет свой дескриптор для записываемого конца, wait()
# быстро сообщит о читаемом конце как о прочитанном.
w
.
close
()
while
readers
:
for
r
in
wait
(
readers
):
try
:
msg
=
r
.
recv
()
except
EOFError
:
readers
.
remove
(
r
)
else
:
print
(
msg
)
Форматы адреса
¶
Адрес
'AF_INET'
- кортеж формы
(hostname,
port)
, где
hostname
- строка, а
port
- целое число.
Адрес
'AF_UNIX'
- это строка, представляющий имя файла в файловой
системе.
Адрес
'AF_PIPE'
представляет собой строку вида
r'\\.\pipe{PipeName}'
. Чтобы использовать
Client()
для
подключения к именованному каналу на удаленном компьютере с именем
ServerName
,
вместо этого следует использовать адрес формы
r'\
ServerName
\pipe{PipeName}'
.
Обратите внимание, что любая строка, начинающаяся с двух обратных косых
черт, по умолчанию принимается как
'AF_PIPE'
адрес, а не
'AF_UNIX'
адрес.
Ключи аутентификации
¶
Когда каждый использует
Connection.recv
, полученными данными является автоматически
unpickled. К сожалению, отмена извлечения данных из ненадежного источника
является угрозой безопасности. Поэтому
Listener
и
Client()
используйте
модуль
hmac
для обеспечения дайджест-аутентификации.
Ключ аутентификации - это байт строка, который можно рассматривать как
пароль: после установления соединения оба конца потребуют подтверждения того,
что другой знает ключ аутентификации. (Демонстрирующий то, что оба конца
используют тот же ключ, делает
не
, включают отправку ключа по связи.)
Если идентификацию запрошенный, но никакой ключ идентификации не определен
тогда, возвращает значение
current_process().authkey
- используемый (см.
Process
). Этот
значение будет автоматически унаследован любым объектом
Process
, что
текущий процесс создает. Это означает, что (по умолчанию) все процессы
многопроцессорной программы будут совместно использовать один ключ
аутентификации, который может быть используемый при установке соединений между
собой.
Подходящие ключи аутентификации также могут быть сгенерированы с использованием
os.urandom()
.
Логирование
¶
Доступна некоторая поддержка логирование. Однако следует отметить, что пакет
logging
не использует общие блокировки процессов, что позволяет (в
зависимости от типа обработчик) смешивать сообщения из различных процессов.
multiprocessing.
get_logger
(
)
¶
Возвращает логгер используемый по
multiprocessing
. При необходимости будет создан
новый.
При первом создании логгер имеет уровень
logging.NOTSET
и не имеет обработчик
по умолчанию. Сообщения, отправляемые этому логгер, по умолчанию не
распространяются на корневой логгер.
Обратите внимание, что в Windows дочерние процессы наследуют только уровень
логгер родительского процесса - любая другая настройка логгер не
наследуется.
multiprocessing.
log_to_stderr
(
)
¶
Эта функция выполняет вызов
get_logger()
, но в дополнение к возвращению
логгер, созданного get_logger, она добавляет обработчик, который
отправляет вывод в
sys.stderr
, используя формат
'[%(levelname)s/%(processName)s]
%(message)s'
.
Ниже приведен пример сеанса с включенной функцией логирование:
>>>
>>>
import
multiprocessing
,
logging
>>>
logger
=
multiprocessing
.
log_to_stderr
()
>>>
logger
.
setLevel
(
logging
.
INFO
)
>>>
logger
.
warning
(
'doomed'
)
[WARNING/MainProcess] doomed
>>>
m
=
multiprocessing
.
Manager
()
[INFO/SyncManager-...] child process calling self.run()
[INFO/SyncManager-...] created temp directory /.../pymp-...
[INFO/SyncManager-...] manager serving at '/.../listener-...'
>>>
del
m
[INFO/MainProcess] sending shutdown message to manager
[INFO/SyncManager-...] manager exiting with exitcode 0
Полную таблицу уровней логирование см. в модуле
logging
.
Модуль
multiprocessing.dummy
¶
multiprocessing.dummy
копирует API
multiprocessing
, но является не
более чем оболочкой для модуля
threading
.
В частности, функция
Pool
, предоставляемая
multiprocessing.dummy
,
возвращает экземпляр
ThreadPool
, который является подклассом
Pool
, который поддерживает все те же вызовы методов, но использует пул
рабочих потоков, а не рабочих процессов.
class
multiprocessing.pool.
ThreadPool
(
[
processes
[
,
initializer
[
,
initargs
]
]
]
)
¶
Объект пула потоков, который управляет пулом рабочих потоков, которым могут быть
отправлены задания. Экземпляры
ThreadPool
полностью совместимы по
интерфейсу с экземплярами
Pool
, и их ресурсами также необходимо
правильно управлять, используя пул в качестве диспетчера контекста или вызывая
close()
и
terminate()
вручную.
processes
- количество используемых рабочих
потоков. Если
processes
-
None
, то используется номер, возвращенный
os.cpu_count()
.
Если
initializer
не
None
, то каждый рабочий процесс при запуске будет
вызывать
initializer(*initargs)
.
В отличие от
Pool
,
maxtasksperchild
и
context
не могут быть
предоставлены.
Примечание
ThreadPool
имеет тот же интерфейс, что и
Pool
, который
разработан на основе пула процессов и предшествует введению модуля
concurrent.futures
. Таким образом, он наследует некоторые операции,
которые не имеют смысла для пула, поддерживаемого потоками, и имеет свой
собственный тип для представления состояния асинхронных заданий,
AsyncResult
, который не понимается никакими другими библиотеками.
Пользователям обычно следует использовать
concurrent.futures.ThreadPoolExecutor
, который имеет более простой
интерфейс, изначально спроектированный для потоков, и который возвращает
экземпляры
concurrent.futures.Future
, совместимые со многими другими
библиотеками, включая
asyncio
.
Программирование рекомендаций
¶
Существуют определенные руководящие принципы и идиомы, которых следует
придерживаться при использовании
multiprocessing
.
Все методы начала
¶
Следующее относится ко всем методам запуска.
Избегайте разделенного состояние
Насколько это возможно, следует стараться избегать переноса больших объемов
данных между процессами.
Вероятно, лучше всего использовать очереди или пайпы для обмена данными
между процессами, чем использовать примитивы синхронизации более низкого уровня.
Picklability
Убедитесь в том, что аргументы для методов прокси-серверов доступны.
Безопасность потоков прокси
Не используйте прокси-объект из нескольких поток, если вы не защитите его
с помощью блокировки.
(Никогда нет проблемы с различными процессами, используя прокси
same
.)
Присоединение к процессам зомби
В Unix, когда процесс заканчивается, но не был присоединен, он становится зомби.
Никогда не должно быть очень многих, потому что каждый раз новый процесс
начинается (или
active_children()
называют), все законченные процессы,
к которым еще
не присоединились, будет присоединен. Кроме того, вызов
Process.is_alive
завершенного
процесса присоединится к процессу. Тем не менее, это, вероятно, хорошая
практика, чтобы явно присоединиться ко всем процессам, которые вы начинаете.
Лучше наследовать, чем pickle/unpickle
При использовании методов запуска
spawn
или
forkserver
многие типы из
multiprocessing
должны быть подбираемыми, чтобы их могли использовать дочерние
процессы. Однако обычно следует избегать отправки общих объектов другим
процессам с использованием пайпов или очередей. Вместо этого следует
упорядочить программу так, чтобы процесс, которому необходим доступ к общему
ресурсу, созданному в другом месте, мог наследовать его от предшествующего
процесса.
Постарайтесь не заканчивать процессы
Используя метод
Process.terminate
, чтобы
остановить процесс склонно заставить любые
общие ресурсы (такие как замки, семафоры, пайпы и очереди) в настоящее время
являющийся используемый процессом становиться сломанными или недоступными к
другим процессам.
Поэтому, вероятно, лучше только рассмотреть использование
Process.terminate
на
процессах, которые никогда не используют общих ресурсов.
Объединение процессов, использующих очереди
Следует иметь в виду, что процесс, поставивший элементы в очередь, будет ждать
завершения до тех пор, пока все буферизированные элементы не будут поданы
«питателем» поток в нижележащий пайп. (Дочерний процесс может
вызвать метод
Queue.cancel_join_thread
очереди, чтобы избежать такого поведения.
Это означает, что при каждом использовании очереди необходимо убедиться, что все
элементы, помещенные в очередь, будут удалены до присоединения процесса. В
противном случае вы не можете быть уверены, что процессы, поставившие элементы в
очередь, завершатся. Также следует помнить, что недемонические процессы будут
присоединяться автоматически.
Примером взаимоблокировки является следующее:
from
multiprocessing
import
Process
,
Queue
def
f
(
q
):
q
.
put
(
'X'
*
1000000
)
if
__name__
==
'__main__'
:
queue
=
Queue
()
p
=
Process
(
target
=
f
,
args
=
(
queue
,))
p
.
start
()
p
.
join
()
# это мертвая блокировка
obj
=
queue
.
get
()
Фиксация здесь должна была бы обменять последние две линии (или просто удалить
линию
p.join()
).
Явная передача ресурсов дочерним процессам
На Unix, используя метод начала
fork
, дочерний процесс может использовать
общий ресурс, созданный в родительском процессе, используя глобальный ресурс.
Однако лучше передать объект в качестве аргумента конструктору для дочернего
процесса.
Кроме обеспечения совместимости код (потенциально) с Windows и другими
методами запуска, это также гарантирует, что до тех пор, пока дочерний процесс
еще жив, объект не будет мусором собран в родительском процессе. Это может быть
важно, если какой-либо ресурс освобождается при сборе мусора объекта в
родительском процессе.
Таким образом для сущность:
from
multiprocessing
import
Process
,
Lock
def
f
():
...
сделать
что
-
то
используя
"lock"
...
if
__name__
==
'__main__'
:
lock
=
Lock
()
for
i
in
range
(
10
):
Process
(
target
=
f
)
.
start
()
следует переписать как:
from
multiprocessing
import
Process
,
Lock
def
f
(
l
):
...
сделать
что
-
нибудь
,
используя
"l"
...
if
__name__
==
'__main__'
:
lock
=
Lock
()
for
i
in
range
(
10
):
Process
(
target
=
f
,
args
=
(
lock
,))
.
start
()
Остерегайтесь замены
sys.stdin
на «файл, как объект»
multiprocessing
изначально безоговорочно вызвается:
os
.
close
(
sys
.
stdin
.
fileno
())
в методе
multiprocessing.Process._bootstrap()
— это привело к проблемам
с процессами в процессах. Это было изменено на:
sys
.
stdin
.
close
()
sys
.
stdin
=
open
(
os
.
open
(
os
.
devnull
,
os
.
O_RDONLY
),
closefd
=
False
)
Который решает основную проблему процессов, сталкивающихся друг с другом
приводящим к плохой ошибке файла дескриптор, но вводит потенциальную опасность
для заявлений, которые заменяют
sys.stdin()
«подобным файлу объектом» с
буферизующей продукцией. Эта опасность заключается в том, что если несколько
процессов вызывают
close()
на этом файловом объекте, это может привести к
тому, что одни и те же данные будут очищены на объекте несколько раз, что
приведет к повреждению.
Если вы пишете подобный файлу объект и осуществляете ваш собственный
кэширование, вы можете сделать его безопасным от вилки, храня pid каждый раз,
когда вы прилагаете к кэш и отказу от кэш, когда pid изменяется.
Например:
@property
def
cache
(
self
):
pid
=
os
.
getpid
()
if
pid
!=
self
.
_pid
:
self
.
_pid
=
pid
self
.
_cache
=
[]
return
self
.
_cache
Дополнительные сведения см. в разделах
bpo-5155
,
bpo-5313
и
bpo-5331
Методы запуска
spawn
и
forkserver
¶
Есть некоторые дополнительное ограничение, которые не относятся к методу начала
fork
.
Больше picklability
Убедитесь, что все аргументы для
Process.__init__()
доступны. Кроме того, если вы,
подкласс
Process
тогда удостоверяется, что сущности будет picklable,
когда метод
Process.start
назовут.
Глобальные переменные
Принять во внимание, что, если пробег код в дочернем процессе пытается
получить доступ к глобальной переменной, то значение он видит (если таковые
имеются) может не совпасть с значение в родительском процессе в то время,
когда вызван
Process.start
.
Однако глобальные переменные, являющиеся только константами уровня модуля, не
вызывают проблем.
Безопасный импорт основного модуля
Удостоверьтесь, что главный модуль может быть безопасно импортирован новым
Python интерпретатор, не вызывая непреднамеренные побочные эффекты (такой
старт нового процесса).
Например, использование метода начала
spawn
или
forkserver
, управляющего
следующим модулем, потерпело бы неудачу с
RuntimeError
:
from
multiprocessing
import
Process
def
foo
():
print
(
'hello'
)
p
=
Process
(
target
=
foo
)
p
.
start
()
Вместо этого следует защитить «точку входа» программы, используя
if
__name__
==
'__main__':
следующим образом:
from
multiprocessing
import
Process
,
freeze_support
,
set_start_method
def
foo
():
print
(
'hello'
)
if
__name__
==
'__main__'
:
freeze_support
()
set_start_method
(
'spawn'
)
p
=
Process
(
target
=
foo
)
p
.
start
()
(Строка
freeze_support()
может быть опущена, если программа будет запущена нормально,
а не заморожена.
Это позволяет недавно порожденному Python интерпретатор безопасно
импортировать модуль и затем управлять функцией
foo()
модуля.
Аналогичные ограничения применяются в случае создания пула или менеджера в
главном модуле.
Примеры
¶
Демонстрация создания и использования настраиваемых менеджеров и прокси:
from
multiprocessing
import
freeze_support
from
multiprocessing.managers
import
BaseManager
,
BaseProxy
import
operator
##
class
Foo
:
def
f
(
self
):
print
(
'you called Foo.f()'
)
def
g
(
self
):
print
(
'you called Foo.g()'
)
def
_h
(
self
):
print
(
'you called Foo._h()'
)
# A simple generator function
def
baz
():
for
i
in
range
(
10
):
yield
i
*
i
# Proxy type for generator objects
class
GeneratorProxy
(
BaseProxy
):
_exposed_
=
[
'__next__'
]
def
__iter__
(
self
):
return
self
def
__next__
(
self
):
return
self
.
_callmethod
(
'__next__'
)
# Function to return the operator module
def
get_operator_module
():
return
operator
##
class
MyManager
(
BaseManager
):
pass
# register the Foo class; make `f()` and `g()` accessible via proxy
MyManager
.
register
(
'Foo1'
,
Foo
)
# register the Foo class; make `g()` and `_h()` accessible via proxy
MyManager
.
register
(
'Foo2'
,
Foo
,
exposed
=
(
'g'
,
'_h'
))
# register the generator function baz; use `GeneratorProxy` to make proxies
MyManager
.
register
(
'baz'
,
baz
,
proxytype
=
GeneratorProxy
)
# register get_operator_module(); make public functions accessible via proxy
MyManager
.
register
(
'operator'
,
get_operator_module
)
##
def
test
():
manager
=
MyManager
()
manager
.
start
()
print
(
'-'
*
20
)
f1
=
manager
.
Foo1
()
f1
.
f
()
f1
.
g
()
assert
not
hasattr
(
f1
,
'_h'
)
assert
sorted
(
f1
.
_exposed_
)
==
sorted
([
'f'
,
'g'
])
print
(
'-'
*
20
)
f2
=
manager
.
Foo2
()
f2
.
g
()
f2
.
_h
()
assert
not
hasattr
(
f2
,
'f'
)
assert
sorted
(
f2
.
_exposed_
)
==
sorted
([
'g'
,
'_h'
])
print
(
'-'
*
20
)
it
=
manager
.
baz
()
for
i
in
it
:
print
(
'<
%d
>'
%
i
,
end
=
' '
)
print
()
print
(
'-'
*
20
)
op
=
manager
.
operator
()
print
(
'op.add(23, 45) ='
,
op
.
add
(
23
,
45
))
print
(
'op.pow(2, 94) ='
,
op
.
pow
(
2
,
94
))
print
(
'op._exposed_ ='
,
op
.
_exposed_
)
##
if
__name__
==
'__main__'
:
freeze_support
()
test
()
Использование
Pool
:
import
multiprocessing
import
time
import
random
import
sys
#
# Functions used by test code
#
def
calculate
(
func
,
args
):
result
=
func
(
*
args
)
return
'
%s
says that
%s%s
=
%s
'
%
(
multiprocessing
.
current_process
()
.
name
,
func
.
__name__
,
args
,
result
)
def
calculatestar
(
args
):
return
calculate
(
*
args
)
def
mul
(
a
,
b
):
time
.
sleep
(
0.5
*
random
.
random
())
return
a
*
b
def
plus
(
a
,
b
):
time
.
sleep
(
0.5
*
random
.
random
())
return
a
+
b
def
f
(
x
):
return
1.0
/
(
x
-
5.0
)
def
pow3
(
x
):
return
x
**
3
def
noop
(
x
):
pass
#
# Test code
#
def
test
():
PROCESSES
=
4
print
(
'Creating pool with
%d
processes
\n
'
%
PROCESSES
)
with
multiprocessing
.
Pool
(
PROCESSES
)
as
pool
:
#
# Tests
#
TASKS
=
[(
mul
,
(
i
,
7
))
for
i
in
range
(
10
)]
+
\
[(
plus
,
(
i
,
8
))
for
i
in
range
(
10
)]
results
=
[
pool
.
apply_async
(
calculate
,
t
)
for
t
in
TASKS
]
imap_it
=
pool
.
imap
(
calculatestar
,
TASKS
)
imap_unordered_it
=
pool
.
imap_unordered
(
calculatestar
,
TASKS
)
print
(
'Ordered results using pool.apply_async():'
)
for
r
in
results
:
print
(
'
\t
'
,
r
.
get
())
print
()
print
(
'Ordered results using pool.imap():'
)
for
x
in
imap_it
:
print
(
'
\t
'
,
x
)
print
()
print
(
'Unordered results using pool.imap_unordered():'
)
for
x
in
imap_unordered_it
:
print
(
'
\t
'
,
x
)
print
()
print
(
'Ordered results using pool.map() --- will block till complete:'
)
for
x
in
pool
.
map
(
calculatestar
,
TASKS
):
print
(
'
\t
'
,
x
)
print
()
#
# Test error handling
#
print
(
'Testing error handling:'
)
try
:
print
(
pool
.
apply
(
f
,
(
5
,)))
except
ZeroDivisionError
:
print
(
'
\t
Got ZeroDivisionError as expected from pool.apply()'
)
else
:
raise
AssertionError
(
'expected ZeroDivisionError'
)
try
:
print
(
pool
.
map
(
f
,
list
(
range
(
10
))))
except
ZeroDivisionError
:
print
(
'
\t
Got ZeroDivisionError as expected from pool.map()'
)
else
:
raise
AssertionError
(
'expected ZeroDivisionError'
)
try
:
print
(
list
(
pool
.
imap
(
f
,
list
(
range
(
10
)))))
except
ZeroDivisionError
:
print
(
'
\t
Got ZeroDivisionError as expected from list(pool.imap())'
)
else
:
raise
AssertionError
(
'expected ZeroDivisionError'
)
it
=
pool
.
imap
(
f
,
list
(
range
(
10
)))
for
i
in
range
(
10
):
try
:
x
=
next
(
it
)
except
ZeroDivisionError
:
if
i
==
5
:
pass
except
StopIteration
:
break
else
:
if
i
==
5
:
raise
AssertionError
(
'expected ZeroDivisionError'
)
assert
i
==
9
print
(
'
\t
Got ZeroDivisionError as expected from IMapIterator.next()'
)
print
()
#
# Testing timeouts
#
print
(
'Testing ApplyResult.get() with timeout:'
,
end
=
' '
)
res
=
pool
.
apply_async
(
calculate
,
TASKS
[
0
])
while
1
:
sys
.
stdout
.
flush
()
try
:
sys
.
stdout
.
write
(
'
\n\t
%s
'
%
res
.
get
(
0.02
))
break
except
multiprocessing
.
TimeoutError
:
sys
.
stdout
.
write
(
'.'
)
print
()
print
()
print
(
'Testing IMapIterator.next() with timeout:'
,
end
=
' '
)
it
=
pool
.
imap
(
calculatestar
,
TASKS
)
while
1
:
sys
.
stdout
.
flush
()
try
:
sys
.
stdout
.
write
(
'
\n\t
%s
'
%
it
.
next
(
0.02
))
except
StopIteration
:
break
except
multiprocessing
.
TimeoutError
:
sys
.
stdout
.
write
(
'.'
)
print
()
print
()
if
__name__
==
'__main__'
:
multiprocessing
.
freeze_support
()
test
()
Пример использования очередей для подачи задач в коллекцию рабочих процессов и
сбора результатов: |
| Markdown | ### Навигация
- [указатель](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/genindex.html "Алфавитный указатель")
- [модули](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/py-modindex.html "Содержание модулей Python") \|
- [вперёд](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.shared_memory.html "multiprocessing.shared_memory — Предоставляет общую память для прямого доступа между процессами") \|
- [назад](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html "threading — Потоковый параллелизм") \|
- 
- [Python](https://digitology.tech/) »
- [3\.8.8 Документация](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/index.html) »
- [Стандартная библиотека Python](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/index.html) »
- [Конкурентное выполнение](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/concurrency.html) »
- \|
[Поддержать первод](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/donate.html)
# [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") — Процессный параллелизм[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "Ссылка на этот заголовок")
**Исходный код:** [Lib/multiprocessing/](https://github.com/python/cpython/tree/3.8/Lib/multiprocessing/)
***
## Введение[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id1 "Ссылка на этот заголовок")
[`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") - это пакет, который поддерживает порождение процессов с использованием API, похожим на модуль [`threading`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#module-threading "threading: Потоковый параллелизм."). Пакет [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") предлагает как локальный, так и удаленный параллелизм, эффективно обходя [Глобальную блокировку интерпретатора](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/glossary.html#term-52) с использованием подпроцессов вместо потоков. Также модуль [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") позволяет программисту полностью использовать несколько процессоров на данном компьютере. Работает как на Unix, так и на Windows.
Модуль [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") также вводит API, которые не имеет аналогов в модуле [`threading`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#module-threading "threading: Потоковый параллелизм."). Ярким примером этого является объект [`Pool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "multiprocessing.pool.Pool"), который предлагает удобное средство параллелирования выполнения функции по множеству входных значениц, распределения входных данных по процессам (параллелизм данных). Следующий пример демонстрирует обычную практику определения таких функций в модуле, чтобы дочерние процессы могли успешно импортировать этот модуль. Этот базовый пример параллелизма данных с использованием [`Pool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "multiprocessing.pool.Pool"):
```
from multiprocessing import Pool
def f(x):
return x*x
if __name__ == '__main__':
with Pool(5) as p:
print(p.map(f, [1, 2, 3]))
```
будет напечатано в стандартный вывод:
```
[1, 4, 9]
```
### Класс [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process")[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#process "Ссылка на этот заголовок")
В [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") процессы порождаются созданием объекта [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process"), а затем вызовом его метода [`start()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.start "multiprocessing.Process.start"). [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process") следует API [`threading.Thread`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Thread "threading.Thread"). Тривиальный пример многопроцессорной программы:
```
from multiprocessing import Process
def f(name):
print('hello', name)
if __name__ == '__main__':
p = Process(target=f, args=('bob',))
p.start()
p.join()
```
Ниже приведен развернутый пример, показывающий соответствующие идентификаторы отдельных процессов:
```
from multiprocessing import Process
import os
def info(title):
print(title)
print('module name:', __name__)
print('parent process:', os.getppid())
print('process id:', os.getpid())
def f(name):
info('function f')
print('hello', name)
if __name__ == '__main__':
info('main line')
p = Process(target=f, args=('bob',))
p.start()
p.join()
```
Объяснение причины необходимости `if __name__ == '__main__'` части см. в разделе [Программирование рекомендаций](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-programming).
### Контексты и методы запуска[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id2 "Ссылка на этот заголовок")
В зависимости от платформы, [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") поддерживает три способа запуска процесса. Далее перечислены *методы запуска*.
> *spawn*
>
> Родительский процесс запускает новый процесс интерпретатора Python. Дочерний процесс унаследует только те ресурсы, которые необходимы для выполнения метода [`run()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.run "multiprocessing.Process.run") объекта процесса. В частности, ненужные файловые дескрипторы и дескрипторы родительского процесса не будут унаследованы. Запуск процесса с использованием этого метода довольно медленный по сравнению с использованием *fork* или *forkserver*.
>
> Доступно в Unix и Windows. Значение по умолчанию для Windows и macOS.
>
> *fork*
>
> Родительский процесс использует [`os.fork()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/os.html#os.fork "os.fork") для форсирования Python интерпретатор. Дочерний процесс, когда он начинается, фактически идентичен родительскому процессу. Все ресурсы родителя наследуются дочерним процессом. Следует отметить, что безопасная форсировка многопоточного процесса является проблематичной.
>
> Доступно только в Unix. Значение по умолчанию в Unix.
>
> *forkserver*
>
> Когда программа начинает и выбирает метод начала *forkserver*, процесс сервера, начат. С этого момента всякий раз, когда требуется новый процесс, родительский процесс подключается к серверу и запрашивает, чтобы он форсировал новый процесс. Процесс сервера вилки является однопотоковым, поэтому он безопасен для использования [`os.fork()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/os.html#os.fork "os.fork"). Ненужные ресурсы не наследуются.
>
> Доступный на платформах Unix, которые поддерживают мимолетный файл дескрипторы по Unix пайпы.
Изменено в версии 3.8: На macOS метод начала *spawn* - теперь дефолт. Метод запуска *fork* следует считать небезопасным, поскольку он может привести к сбоям подпроцессы. См. [bpo-33725](https://bugs.python.org/issue33725).
Изменено в версии 3.4: *spawn* добавлены на всех платформах unix и *forkserver* добавлены для некоторых платформ unix. Дочерние процессы больше не наследуют все унаследованные родительские дескрипторы в Windows.
В Unix с помощью методов запуска *spawn* или *forkserver* также запускается процесс *resource tracker*, который отслеживает несвязанные именованные системные ресурсы (такие как именованные семафоры или [`SharedMemory`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.shared_memory.html#multiprocessing.shared_memory.SharedMemory "multiprocessing.shared_memory.SharedMemory") объекты), созданные процессами программы. После завершения всех процессов средство отслеживания ресурсов отменяет связь с любым оставшимся отслеживаемым объектом. Обычно их не должно быть, но если какой-либо процесс был убит сигналом, то может возникнуть некоторая «утечка» ресурсов. (Ни просочившиеся семафоры, ни сегменты общей памяти не будут автоматически отключены до следующей перезагрузки. Это проблематично для обоих объектов, поскольку система допускает только ограниченное количество именованных семафоров, а сегменты совместно используемой памяти занимают некоторое место в основной памяти.)
Для выбора метода запуска используется [`set_start_method()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.set_start_method "multiprocessing.set_start_method") в `if __name__ == '__main__'` клаузула основного модуля. Например:
```
import multiprocessing as mp
def foo(q):
q.put('hello')
if __name__ == '__main__':
mp.set_start_method('spawn')
q = mp.Queue()
p = mp.Process(target=foo, args=(q,))
p.start()
print(q.get())
p.join()
```
[`set_start_method()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.set_start_method "multiprocessing.set_start_method") не должны быть используемый более одного раза в программе.
Кроме того, можно использовать [`get_context()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.get_context "multiprocessing.get_context") для получения объекта контекст. Объекты контекста имеют тот же API, что и модуль многопроцессорной обработки, и позволяют использовать несколько методов запуска в одной программе:
```
import multiprocessing as mp
def foo(q):
q.put('hello')
if __name__ == '__main__':
ctx = mp.get_context('spawn')
q = ctx.Queue()
p = ctx.Process(target=foo, args=(q,))
p.start()
print(q.get())
p.join()
```
Обратите внимание, что объекты, связанные с одним контекст, могут быть несовместимы с процессами для другого контекст. В частности, блокировки, созданные с помощью *fork* контекст, не могут быть переданы процессам, запущенным с помощью методов запуска *spawn* или *forkserver*.
Библиотека, которая хочет использовать конкретный метод запуска, должна, вероятно, использовать [`get_context()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.get_context "multiprocessing.get_context"), чтобы избежать вмешательства в выбор пользователя библиотеки.
Предупреждение
Стартовые методы `'spawn'` и `'forkserver'` в настоящее время не могут быть используемый с «замороженными» исполняемыми файлами (т.е. двоичными файлами, создаваемыми пакетами, такими как **PyInstaller** and **cx\_Freeze**) в Unix. Стартовый метод `'fork'` работает.
### Обмен объектами между процессами[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id3 "Ссылка на этот заголовок")
[`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") поддерживает два типа каналов связи между процессами:
**Очереди**
> Класс [`Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue "multiprocessing.Queue") является близким клоном [`queue.Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Queue "queue.Queue"). Например:
> ```
> from multiprocessing import Process, Queue
def f(q):
q.put([42, None, 'hello'])
if __name__ == '__main__':
q = Queue()
p = Process(target=f, args=(q,))
p.start()
print(q.get()) # распечатает "[42, None, 'hello']"
p.join()
> ```
> Очереди поток и безопасны для обработки.
**Пайпы**
> [`Pipe()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Pipe "multiprocessing.Pipe") функционируют возвращает пара объектов связи, связанных пайп, который по умолчанию является (двухсторонним) дуплексом. Например:
> ```
> from multiprocessing import Process, Pipe
def f(conn):
conn.send([42, None, 'hello'])
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv()) # распечатает "[42, None, 'hello']"
p.join()
> ```
> Два объекта соединения возвращенный [`Pipe()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Pipe "multiprocessing.Pipe") представляют два конца пайп. Каждый объект подключения имеет методы `send()` и `recv()` (среди прочих). Обратите внимание, что данные в пайп могут быть повреждены, если два процесса (или потоки) пытаются одновременно считать или записывать в *same* конец пайп. Конечно, нет риска коррупции от процессов, использующих разные концы пайп одновременно.
### Синхронизация между процессами[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id4 "Ссылка на этот заголовок")
[`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") содержит эквиваленты всех примитивов синхронизации из [`threading`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#module-threading "threading: Потоковый параллелизм."). Для сущность можно использовать блокировку для обеспечения одновременной печати только одного процесса в стандартный вывод:
```
from multiprocessing import Process, Lock
def f(l, i):
l.acquire()
try:
print('hello world', i)
finally:
l.release()
if __name__ == '__main__':
lock = Lock()
for num in range(10):
Process(target=f, args=(lock, num)).start()
```
Без использования блокировки выходные данные различных процессов могут быть смешаны.
### Совместное использование состояние между процессами[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id5 "Ссылка на этот заголовок")
Как упомянуто выше, когда выполнение параллельного программирования его является обычно лучшим избегать использования разделенного состояние в максимально возможной степени. Это особенно верно при использовании нескольких процессов.
Однако, если вам действительно нужно использовать некоторые общие данные, то [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") предоставляет пару способов сделать это.
**Общая память**
> Данные могут храниться в карте совместно используемой памяти с помощью [`Value`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Value "multiprocessing.Value") или [`Array`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Array "multiprocessing.Array"). Например, следующие код:
> ```
> from multiprocessing import Process, Value, Array
def f(n, a):
n.value = 3.1415927
for i in range(len(a)):
a[i] = -a[i]
if __name__ == '__main__':
num = Value('d', 0.0)
arr = Array('i', range(10))
p = Process(target=f, args=(num, arr))
p.start()
p.join()
print(num.value)
print(arr[:])
> ```
> напечатает:
> ```
> 3.1415927
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
> ```
> Аргументы `'d'` и `'i'` используемый при создании `num` и `arr` являются типкодами вида используемый модулем [`array`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/array.html#module-array "array: Пространственно-эффективные массивы типизированных числовых значений."): `'d'` указывает двойную точность float и `'i'` обозначает целое число со знаком. Эти общие объекты будут процессом и потокобезопасной.
>
> Для большей гибкости в использовании совместно используемой памяти можно использовать модуль [`multiprocessing.sharedctypes`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.sharedctypes "multiprocessing.sharedctypes: Аллоцировать объекты ctypes из общей памяти."), поддерживающий создание объектов произвольных ctypes, выделенных из совместно используемой памяти.
**Серверный процесс**
> Объект менеджера возвращенный `Manager()` управляет серверным процессом, который содержит объекты Python и позволяет другим процессам манипулировать ими с помощью прокси.
>
> Менеджер возвращенный `Manager()` поддержит типы [`list`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#list "list"), `dict`, [`Namespace`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.Namespace "multiprocessing.managers.Namespace"), [`Lock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock "multiprocessing.Lock"), [`RLock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.RLock "multiprocessing.RLock"), [`Semaphore`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Semaphore "multiprocessing.Semaphore"), [`BoundedSemaphore`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.BoundedSemaphore "multiprocessing.BoundedSemaphore"), [`Condition`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Condition "multiprocessing.Condition"), [`Event`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Event "multiprocessing.Event"), [`Barrier`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Barrier "multiprocessing.Barrier"), [`Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue "multiprocessing.Queue"), [`Value`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Value "multiprocessing.Value") и [`Array`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Array "multiprocessing.Array"). Например,:
> ```
> from multiprocessing import Process, Manager
def f(d, l):
d[1] = '1'
d['2'] = 2
d[0.25] = None
l.reverse()
if __name__ == '__main__':
with Manager() as manager:
d = manager.dict()
l = manager.list(range(10))
p = Process(target=f, args=(d, l))
p.start()
p.join()
print(d)
print(l)
> ```
> напечатает:
> ```
> {0.25: None, 1: '1', '2': 2}
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
> ```
> Менеджеры серверных процессов более гибки, чем использование общих объектов памяти, поскольку они могут быть созданы для поддержки произвольных типов объектов. Кроме того, один менеджер может совместно использоваться процессами на разных компьютерах по сети. Однако они работают медленнее, чем совместно используемая память.
### Использование пула воркеров[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id6 "Ссылка на этот заголовок")
Класс [`Pool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "multiprocessing.pool.Pool") представляет пул рабочих процессов. Он содержит методы, позволяющие выгружать задачи в рабочие процессы несколькими различными способами.
Например:
```
from multiprocessing import Pool, TimeoutError
import time
import os
def f(x):
return x*x
if __name__ == '__main__':
# запуск 4 рабочих процессов
with Pool(processes=4) as pool:
# печать "[0, 1, 4,..., 81]"
print(pool.map(f, range(10)))
# печатать одинаковые числа в произвольном порядке
for i in pool.imap_unordered(f, range(10)):
print(i)
# вычислить "f(20)" асинхронно
res = pool.apply_async(f, (20,)) # запускается в *только* одном процессе
print(res.get(timeout=1)) # печатает "400"
# вычислить "os.getpid()" асинхронно
res = pool.apply_async(os.getpid, ()) # запускается в *только* одном процессе
print(res.get(timeout=1)) # печатает PID этого процесса
# запуск нескольких оценок асинхронно *может* использовать больше процессов
multiple_results = [pool.apply_async(os.getpid, ()) for i in range(4)]
print([res.get(timeout=1) for res in multiple_results])
# уснуть одному рабочему на 10 секунд
res = pool.apply_async(time.sleep, (10,))
try:
print(res.get(timeout=1))
except TimeoutError:
print("We lacked patience and got a multiprocessing.TimeoutError")
print("For the moment, the pool remains available for more work")
# выход из блока with с остановкой пула
print("Now the pool is closed and no longer available")
```
Обратите внимание, что методы бассейна должны только когда-либо быть используемый процессом, который создал его.
Примечание
Функциональность этого пакета требует, чтобы модуль `__main__` был импортирован нижестоящими элементами. Это освещено в [Программирование рекомендаций](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-programming), однако здесь стоит указать. Это означает, что некоторые примеры, такие как примеры [`multiprocessing.pool.Pool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "multiprocessing.pool.Pool") не будут работать в интерактивном интерпретатор. Например:
\>\>\>
```
>>> from multiprocessing import Pool
>>> p = Pool(5)
>>> def f(x):
... return x*x
...
>>> with p:
... p.map(f, [1,2,3])
Process PoolWorker-1:
Process PoolWorker-2:
Process PoolWorker-3:
Traceback (most recent call last):
AttributeError: 'module' object has no attribute 'f'
AttributeError: 'module' object has no attribute 'f'
AttributeError: 'module' object has no attribute 'f'
```
(Если попробовать это, то на самом деле будет выведено три полных трейсбэки, перемежающихся полуслучайным образом, а затем, возможно, придется как-то остановить родительский процесс.
## Ссылка[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id7 "Ссылка на этот заголовок")
Пакет [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") в основном реплицирует API модуля [`threading`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#module-threading "threading: Потоковый параллелизм.").
### [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process") и исключения[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id8 "Ссылка на этот заголовок")
*class* `multiprocessing.``Process`(*group=None*, *target=None*, *name=None*, *args=()*, *kwargs={}*, *\**, *daemon=None*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "Ссылка на это определение")
Объекты процесса представляют собой операцию, выполняемую в отдельном процессе. Класс [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process") имеет эквиваленты всех методов [`threading.Thread`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Thread "threading.Thread").
Конструктор всегда должен вызываться с аргументами ключевой. *group* всегда должны быть `None`; он существует исключительно для совместимости с [`threading.Thread`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Thread "threading.Thread"). *target* - вызываемый объект, вызываемый методом [`run()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.run "multiprocessing.Process.run"). По умолчанию он имеет значение `None`, то есть ничего не называется. *name* - имя процесса (более подробную информацию см. в разделе [`name`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.name "multiprocessing.Process.name")). *args* - кортеж аргументов для целевого вызова. *kwargs* - словарь ключевой аргументов для целевого вызова. Если указано, только ключевой аргумент *daemon* задает для флага процесса [`daemon`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.daemon "multiprocessing.Process.daemon") значение `True` или `False`. Если значение равно `None` (по умолчанию), этот флаг наследуется от процесса создания.
По умолчанию аргументы не передаются *target*.
Если подкласс отвергает конструктора, он должен удостовериться, что призывает конструктора базового класса (`Process.__init__()`) прежде, чем сделать что-либо еще к процессу.
Изменено в версии 3.3: Добавлен аргумент *daemon*.
`run`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.run "Ссылка на это определение")
Метод, представляющий активность процесса.
Этот метод можно переопределить в подкласс. Стандартный метод [`run()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.run "multiprocessing.Process.run") призывает подлежащий выкупу объект, переданный конструктору объекта как целевой аргумент, если таковые имеются, с последовательными и аргументами ключевой, взятыми от *args* и аргументов *kwargs*, соответственно.
`start`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.start "Ссылка на это определение")
Запустите действие процесса.
Это должно вызываться не более одного раза для каждого объекта процесса. Она обеспечивает возможность вызова метода [`run()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.run "multiprocessing.Process.run") объекта в отдельном процессе.
`join`(\[*timeout*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.join "Ссылка на это определение")
Если необязательным аргументом *timeout* является `None` (по умолчанию), метод блокируется до завершения процесса, метод [`join()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.join "multiprocessing.Process.join") которого вызывается. Если *timeout* - положительное число, оно блокируется максимум через *timeout* секунд. Обратите внимание, что метод возвращает `None`, если его процесс завершается или время ожидания метода истекло. Проверьте [`exitcode`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.exitcode "multiprocessing.Process.exitcode") процесса, чтобы определить его завершение.
Процесс может быть объединен много раз.
Процесс не может присоединиться к самому себе, поскольку это приведет к взаимоблокировке. Ошибка при попытке присоединения к процессу перед его запуском.
`name`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.name "Ссылка на это определение")
Имя процесса. Имя - строка используемый в идентификационных целях только. У него нет семантики. Нескольким процессам может быть присвоено одно и то же имя.
Начальное имя задается конструктором. Если для конструктора не указано явное имя, создается имя формы „Process-N:sub:1: N:sub:2:…: N:sub:k“, где каждый Nk является N-м потомком своего родителя.
`is_alive`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.is_alive "Ссылка на это определение")
Возвращает жив ли процесс.
Примерно, объект процесса жив с момента возвращает метода [`start()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.start "multiprocessing.Process.start") до завершения дочернего процесса.
`daemon`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.daemon "Ссылка на это определение")
Флаг демона процесса, логический значение. Это должно быть установлено, прежде чем [`start()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.start "multiprocessing.Process.start") называют.
Начальный значение унаследован от процесса создания.
Когда процесс завершается, он пытается завершить все свои демонические дочерние процессы.
Обратите внимание, что демоническому процессу запрещено создавать дочерние процессы. В противном случае демонический процесс оставит своих потомков сиротами, если он завершится после завершения родительского процесса. Кроме того, это демоны или службы **не** Unix, это обычные процессы, которые будут прекращены (и не присоединены), если не демонические процессы вышли.
В дополнение к [`threading.Thread`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Thread "threading.Thread") API объекты [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process") также поддерживают следующий атрибуты и methods:
`pid`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.pid "Ссылка на это определение")
Возвращает идентификатор процесса. Перед началом процесса это будет `None`.
`exitcode`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.exitcode "Ссылка на это определение")
Выход ребенка код. Это будет `None`, если процесс еще не завершен. Отрицательный значение *\-N* указывает на то, что дочерний объект был завершен сигналом *N*.
`authkey`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.authkey "Ссылка на это определение")
Ключ аутентификации процесса (байтовая строка).
Когда [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") инициализируется, основному процессу присваивается случайный строка с помощью [`os.urandom()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/os.html#os.urandom "os.urandom").
При создании объекта [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process") он наследует ключ аутентификации родительского процесса, хотя его можно изменить, установив для параметра [`authkey`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.authkey "multiprocessing.Process.authkey") значение другого байта строка.
См. [Ключи аутентификации](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-auth-keys).
`sentinel`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.sentinel "Ссылка на это определение")
Числовой дескриптор системного объекта, который становится «готовым» по завершении процесса.
Вы можете использовать этот значение, если вы хотите ждать на нескольких событиях, сразу используя [`multiprocessing.connection.wait()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.wait "multiprocessing.connection.wait"). В противном случае вызов [`join()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.join "multiprocessing.Process.join") проще.
В Windows это дескриптор ОС, используемый с семейством вызовов API `WaitForSingleObject` и `WaitForMultipleObjects`. На Unix это - файл дескриптор, применимый с примитивами от модуля [`select`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/select.html#module-select "select: Дождаться завершения I/O в нескольких потоках.").
Добавлено в версии 3.3.
`terminate`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.terminate "Ссылка на это определение")
Завершить процесс. В Unix это выполняется с помощью сигнала `SIGTERM`; на Windows используется `TerminateProcess()`. Следует отметить, что обработчики exit и finally и т.д. выполняться не будут.
Заметим, что потомки процесса *не* будут прекращены - они просто осиротеют.
Предупреждение
Если этот метод является используемый, когда связанный процесс использует пайп или очередь, то пайп или очередь может быть повреждена и может стать непригодной для использования другим процессом. Аналогично, если процесс приобрел блокировку или семафор и т.д., то завершение его может привести к взаимоблокировке других процессов.
`kill`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.kill "Ссылка на это определение")
То же, что и [`terminate()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.terminate "multiprocessing.Process.terminate"), но с использованием сигнала `SIGKILL` в Unix.
Добавлено в версии 3.7.
`close`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.close "Ссылка на это определение")
Закрыть объект [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process"), освободив все связанные с ним ресурсы. [`ValueError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#ValueError "ValueError") возникает, если базовый процесс все еще выполняется. Как только [`close()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.close "multiprocessing.Process.close") возвращает успешно, большинство других методов и атрибуты объекта [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process") поднимут [`ValueError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#ValueError "ValueError").
Добавлено в версии 3.7.
Обратите внимание, что [`start()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.start "multiprocessing.Process.start"), [`join()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.join "multiprocessing.Process.join"), [`is_alive()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.is_alive "multiprocessing.Process.is_alive"), [`terminate()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.terminate "multiprocessing.Process.terminate") и методы [`exitcode`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.exitcode "multiprocessing.Process.exitcode") должен только вызвать процесс, который создал объект процесса.
Пример использования некоторых методов [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process"):
```
>>> import multiprocessing, time, signal
>>> p = multiprocessing.Process(target=time.sleep, args=(1000,))
>>> print(p, p.is_alive())
<Process ... initial> False
>>> p.start()
>>> print(p, p.is_alive())
<Process ... started> True
>>> p.terminate()
>>> time.sleep(0.1)
>>> print(p, p.is_alive())
<Process ... stopped exitcode=-SIGTERM> False
>>> p.exitcode == -signal.SIGTERM
True
```
*exception* `multiprocessing.``ProcessError`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.ProcessError "Ссылка на это определение")
Базовый класс всех исключений [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.").
*exception* `multiprocessing.``BufferTooShort`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.BufferTooShort "Ссылка на это определение")
Исключение, вызванное `Connection.recv_bytes_into()`, когда предоставленный объект буфера слишком мал для чтения сообщения.
Если `e` является сущность [`BufferTooShort`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.BufferTooShort "multiprocessing.BufferTooShort"), то `e.args[0]` передаст сообщение в виде байтовой строки.
*exception* `multiprocessing.``AuthenticationError`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.AuthenticationError "Ссылка на это определение")
Возникает при ошибке проверки подлинности.
*exception* `multiprocessing.``TimeoutError`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.TimeoutError "Ссылка на это определение")
Вызывается методами с тайм-аутом по истечении тайм-аута.
### Пайпы и очереди[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id9 "Ссылка на этот заголовок")
При использовании нескольких процессов обычно используют передачу сообщений для связи между процессами и избегают необходимости использования каких-либо примитивов синхронизации, таких как блокировки.
Для передачи сообщений можно использовать [`Pipe()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Pipe "multiprocessing.Pipe") (для соединения между двумя процессами) или очередь (которая позволяет нескольким производителям и потребителям).
[`Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue "multiprocessing.Queue"), [`SimpleQueue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.SimpleQueue "multiprocessing.SimpleQueue") и типы [`JoinableQueue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.JoinableQueue "multiprocessing.JoinableQueue") - мультипроизводитель, мультипотребитель очереди FIFO, смоделированные на классе [`queue.Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Queue "queue.Queue") в стандартной библиотеке. Они отличаются по тому [`Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue "multiprocessing.Queue"), испытывает недостаток в [`task_done()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Queue.task_done "queue.Queue.task_done") и методах [`join()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Queue.join "queue.Queue.join"), введенных в класс Python 2.5’s [`queue.Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Queue "queue.Queue").
Если вы используете [`JoinableQueue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.JoinableQueue "multiprocessing.JoinableQueue"), то вы **должны** вызвать [`JoinableQueue.task_done()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.JoinableQueue.task_done "multiprocessing.JoinableQueue.task_done") для каждой задачи, удаленной из очереди, или семафор используемый для подсчета количества незавершенных задач может в конечном итоге переполниться, вызывая исключение.
Обратите внимание, что можно также создать общую очередь с помощью объекта менеджера - см. раздел [Менеджеры](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-managers).
Примечание
[`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") использует обычные исключения [`queue.Empty`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Empty "queue.Empty") и [`queue.Full`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Full "queue.Full") для сигнализации тайм-аута. Они недоступны в пространстве имен [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм."), поэтому их необходимо импортировать из [`queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#module-queue "queue: Класс синхронизированной очереди.").
Примечание
Когда объект помещен на очередь, объект - pickled и фон поток более поздние потоки данные pickled к основному пайп. Это имеет некоторые последствия, которые немного удивительны, но не должны вызывать никаких практических трудностей - если они действительно беспокоят вас, то вы можете вместо этого использовать очередь, созданную с [manager](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-managers).
1. После помещения объекта в пустую очередь может произойти бесконечная задержка перед тем, как метод [`empty()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.empty "multiprocessing.Queue.empty") очереди возвращает [`False`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/constants.html#False "False") и [`get_nowait()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.get_nowait "multiprocessing.Queue.get_nowait") может возвращает без повышения [`queue.Empty`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Empty "queue.Empty").
2. если несколько процессов ставят в очередь объекты, возможно, чтобы объекты были приняты на другом конце вне порядка. Однако объекты, поставленные в очередь одним и тем же процессом, всегда будут находиться в ожидаемом порядке относительно друг друга.
Предупреждение
Если процесс был убит с помощью [`Process.terminate()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.terminate "multiprocessing.Process.terminate") или [`os.kill()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/os.html#os.kill "os.kill") во время попытки использования [`Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue "multiprocessing.Queue"), то данные в очереди, вероятно, будут повреждены. Это может привести к тому, что любой другой процесс получит исключение при попытке использовать очередь позже.
Предупреждение
Как упомянуто выше, если дочерний процесс поместил предметы на очередь (и у него нет используемый [`JoinableQueue.cancel_join_thread`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.cancel_join_thread "multiprocessing.Queue.cancel_join_thread")), тогда тот процесс не закончится, пока все буферизированные предметы не смылись (flushed) в пайп.
Это означает, что при попытке присоединения к этому процессу может возникнуть взаимоблокировка, если вы не уверены, что все элементы, помещенные в очередь, были израсходованы. Аналогично, если дочерний процесс не является демоническим, то родительский процесс может зависать на выходе, когда пытается присоединиться ко всем своим недемоническим потомкам.
Обратите внимание, что очередь, созданная с помощью менеджера, не имеет этой проблемы. См. [Программирование рекомендаций](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-programming).
Пример использования очередей для межпроцессной связи см. в разделе [Примеры](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-examples).
`multiprocessing.``Pipe`(\[*duplex*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Pipe "Ссылка на это определение")
Возвращает пару `(conn1, conn2)` объектов [`Connection`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection "multiprocessing.connection.Connection"), представляющих концы пайпа.
Если *duplex* равно `True` (по умолчанию), то пайп является двунаправленным. Если *duplex* - `False` тогда, пайп однонаправлен: `conn1` может только быть используемый для получения сообщений, и `conn2` может только быть используемый для отправки сообщений.
*class* `multiprocessing.``Queue`(\[*maxsize*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue "Ссылка на это определение")
Возвращает общую очередь процесса, реализованную с использованием пайп и нескольких блокировок/семафоров. Когда процесс сначала помещает элемент в очередь, запускается питатель поток, который передает объекты из буфера в пайп.
Обычные исключения [`queue.Empty`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Empty "queue.Empty") и [`queue.Full`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Full "queue.Full") из модуля [`queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#module-queue "queue: Класс синхронизированной очереди.") стандартной библиотеки вызываются тайм-аутами сигнала.
[`Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue "multiprocessing.Queue") реализует все методы [`queue.Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Queue "queue.Queue"), кроме [`task_done()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Queue.task_done "queue.Queue.task_done") и [`join()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Queue.join "queue.Queue.join").
`qsize`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.qsize "Ссылка на это определение")
Возвращает приблизительный размер очереди. Из-за семантики многопоточной/многопроцессорной обработки это число не является надежным.
Обратите внимание, что это может привести к появлению [`NotImplementedError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#NotImplementedError "NotImplementedError") на платформах Unix, таких как Mac OS X, где `sem_getvalue()` не реализован.
`empty`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.empty "Ссылка на это определение")
Возвращает `True`, если очередь пуста, `False` иначе. Из-за семантики многопоточной/многопроцессорной обработки это ненадежно.
`full`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.full "Ссылка на это определение")
Возвращает `True`, если очередь полна, `False` иначе. Из-за семантики многопоточной/многопроцессорной обработки это ненадежно.
`put`(*obj*\[, *block*\[, *timeout*\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.put "Ссылка на это определение")
Поместить объект в очередь. Если дополнительный аргумент *block* имеет значение `True` (по умолчанию), а *timeout* - значение `None` (по умолчанию), при необходимости блокируйте до тех пор, пока свободный слот не будет доступен. Если *timeout* является положительным числом, он блокирует максимум *timeout* секунд и вызывает исключение [`queue.Full`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Full "queue.Full"), если свободный слот не был доступен в течение этого времени. В противном случае (*block* - `False`) Поместить элемент в очередь, если свободный слот немедленно доступен, иначе вызовите исключение [`queue.Full`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Full "queue.Full") (*timeout* игнорируется в этом случае).
Изменено в версии 3.8: Если очередь закрыта, [`ValueError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#ValueError "ValueError") поднят вместо [`AssertionError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#AssertionError "AssertionError").
`put_nowait`(*obj*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.put_nowait "Ссылка на это определение")
Эквивалентный `put(obj, False)`.
`get`(\[*block*\[, *timeout*\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.get "Ссылка на это определение")
Удаление и возвращает элемента из очереди. Если необязательными args *block* является `True` (по умолчанию), а *timeout* - `None` (по умолчанию), при необходимости блокируйте до тех пор, пока элемент не будет доступен. Если *timeout* является положительным числом, он блокирует максимум *timeout* секунд и вызывает исключение [`queue.Empty`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Empty "queue.Empty"), если за это время не было доступно ни одного элемента. В противном случае (блок - `False`), возвращает элемент, если он немедленно доступен, иначе вызовите исключение [`queue.Empty`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Empty "queue.Empty") (в этом случае *timeout* игнорируется).
Изменено в версии 3.8: Если очередь закрыта, [`ValueError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#ValueError "ValueError") поднят вместо [`OSError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#OSError "OSError").
`get_nowait`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.get_nowait "Ссылка на это определение")
Эквивалентный `get(False)`.
[`multiprocessing.Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue "multiprocessing.Queue") имеет несколько дополнительных методов, не найденных в [`queue.Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Queue "queue.Queue"). Эти методы обычно не нужны для большинства код:
`close`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.close "Ссылка на это определение")
Укажите, что текущий процесс больше не будет помещать данные в эту очередь. Фоновый поток завершит работу после очистки всех буферизованных данных в пайп. Это вызывается автоматически при сборе мусора в очередь.
`join_thread`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.join_thread "Ссылка на это определение")
Присоединиться к фоновому потоку. Это может только быть используемый после того, как вызван [`close()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.close "multiprocessing.Queue.close"). Это блокирует до фона выходы поток, гарантируя, что все данные в буфере смылись (flushed) в пайп.
По умолчанию, если процесс не является создателем очереди, при выходе он попытается присоединиться к фоновому поток очереди. Процесс может вызвать [`cancel_join_thread()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.cancel_join_thread "multiprocessing.Queue.cancel_join_thread"), чтобы заставить [`join_thread()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.join_thread "multiprocessing.Queue.join_thread") ничего не делать.
`cancel_join_thread`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.cancel_join_thread "Ссылка на это определение")
Препятствуйте тому, чтобы [`join_thread()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.join_thread "multiprocessing.Queue.join_thread") блокировал. В частности, это предотвращает автоматическое соединение фоновых поток при завершении процесса – см. раздел [`join_thread()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.join_thread "multiprocessing.Queue.join_thread").
Лучшее имя для этого метода может быть `allow_exit_without_flush()`. Вероятно, это приведет к потере поставленных в очередь данных, и вам почти наверняка не потребуется их использовать. Это действительно только в том случае, если необходимо, чтобы текущий процесс немедленно вышел, не дожидаясь очистки поставленных в очередь данных на основной пайп, и вы не заботитесь о потерянных данных.
Примечание
Функциональность этого класса требует функциональной реализации общего семафора в операционной системе хоста. Без него функциональность этого класса будет отключена, и попытки создания экземпляра [`Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue "multiprocessing.Queue") приведут к появлению [`ImportError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#ImportError "ImportError"). Дополнительные сведения см. в разделе [bpo-3770](https://bugs.python.org/issue3770). То же самое относится и к любому из перечисленных ниже типов специализированных очередей.
*class* `multiprocessing.``SimpleQueue`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.SimpleQueue "Ссылка на это определение")
Это упрощенный тип [`Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue "multiprocessing.Queue"), очень близкий к заблокированному [`Pipe`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Pipe "multiprocessing.Pipe").
`empty`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.SimpleQueue.empty "Ссылка на это определение")
Возвращает `True`, если очередь пуста, `False` иначе.
`get`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.SimpleQueue.get "Ссылка на это определение")
Удаление и возвращает элемента из очереди.
`put`(*item*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.SimpleQueue.put "Ссылка на это определение")
Поместить *item* в очередь.
*class* `multiprocessing.``JoinableQueue`(\[*maxsize*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.JoinableQueue "Ссылка на это определение")
[`JoinableQueue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.JoinableQueue "multiprocessing.JoinableQueue"), [`Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue "multiprocessing.Queue") подкласс, представляет собой очередь, которая дополнительно содержит методы [`task_done()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.JoinableQueue.task_done "multiprocessing.JoinableQueue.task_done") и [`join()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.JoinableQueue.join "multiprocessing.JoinableQueue.join").
`task_done`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.JoinableQueue.task_done "Ссылка на это определение")
Укажите, что ранее поставленная в очередь задача завершена. Используется потребителями очереди. Для каждого [`get()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.get "multiprocessing.Queue.get") используемый, чтобы выбрать задачу, последующий вызов [`task_done()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.JoinableQueue.task_done "multiprocessing.JoinableQueue.task_done") сообщает очереди, что обработка задачи завершена.
Если [`join()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Queue.join "queue.Queue.join") в настоящее время заблокирует, то он возобновит, когда все предметы были обработаны (подразумевать, что требование [`task_done()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.JoinableQueue.task_done "multiprocessing.JoinableQueue.task_done") было получено для каждого предмета, который был [`put()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.put "multiprocessing.Queue.put") в очередь).
Вызывает [`ValueError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#ValueError "ValueError"), если вызывается больше раз, чем было элементов, помещенных в очередь.
`join`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.JoinableQueue.join "Ссылка на это определение")
Блокировать до тех пор, пока все элементы в очереди не будут получены и обработаны.
Количество незавершенных задач увеличивается при каждом добавлении элемента в очередь. Счетчик снижается всякий раз, когда потребитель звонит [`task_done()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.JoinableQueue.task_done "multiprocessing.JoinableQueue.task_done"), чтобы указать, что элемент был извлечен, и вся работа над ним завершена. Когда число незавершенных задач падает до нуля, [`join()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Queue.join "queue.Queue.join") разблокирует.
### Разное[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id10 "Ссылка на этот заголовок")
`multiprocessing.``active_children`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.active_children "Ссылка на это определение")
Возвращает список всех живых потомков текущего процесса.
Вызов этого метода имеет побочный эффект «присоединения» к любым уже завершенным процессам.
`multiprocessing.``cpu_count`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.cpu_count "Ссылка на это определение")
Возвращает количество ЦПУ в системе.
Это число не эквивалентно числу ЦПУ, которые может использовать текущий процесс. Количество используемых ЦПУ можно получить с помощью `len(os.sched_getaffinity(0))`
Может поднять [`NotImplementedError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#NotImplementedError "NotImplementedError").
См.также
[`os.cpu_count()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/os.html#os.cpu_count "os.cpu_count")
`multiprocessing.``current_process`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.current_process "Ссылка на это определение")
Возвращает объект [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process"), соответствующий текущему процессу.
Аналог [`threading.current_thread()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.current_thread "threading.current_thread").
`multiprocessing.``parent_process`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.parent_process "Ссылка на это определение")
Возвращает объект [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process"), соответствующий родительскому процессу [`current_process()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.current_process "multiprocessing.current_process"). Для основного процесса `parent_process` будет `None`.
Добавлено в версии 3.8.
`multiprocessing.``freeze_support`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.freeze_support "Ссылка на это определение")
Добавление поддержки в том случае, если программа, использующая [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм."), была заморожена для создания исполняемого файла Windows. (Был проверен с помощью **py2exe**, **PyInstaller** и **cx\_Freeze**.)
Эту функцию необходимо вызвать непосредственно после `if __name__ == '__main__'` линии основного модуля. Например:
```
from multiprocessing import Process, freeze_support
def f():
print('hello world!')
if __name__ == '__main__':
freeze_support()
Process(target=f).start()
```
Если строка `freeze_support()` опущена, то попытка запуска замороженного исполняемого файла вызовет [`RuntimeError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#RuntimeError "RuntimeError").
`freeze_support()` запроса не имеет никакого эффекта, когда он призван на любую операционную систему кроме Windows. Кроме того, если модулем управляет обычно Python интерпретатор на Windows (программа не была заморожена), то `freeze_support()` не имеет никакого эффекта.
`multiprocessing.``get_all_start_methods`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.get_all_start_methods "Ссылка на это определение")
Возвращает список поддерживаемых методов запуска, первым из которых является метод по умолчанию. Возможные методы запуска: `'fork'`, `'spawn'` и `'forkserver'`. В Windows доступен только `'spawn'`. На Unix `'fork'` и `'spawn'` всегда поддерживаются, при этом `'fork'` - дефолт.
Добавлено в версии 3.4.
`multiprocessing.``get_context`(*method=None*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.get_context "Ссылка на это определение")
Возвращает объект контекст, имеющий ту же атрибуты, что и модуль [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.").
Если *method* - `None` тогда дефолт, контекст - возвращенный. В противном случае *method* должны быть `'fork'`, `'spawn'`, `'forkserver'`. [`ValueError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#ValueError "ValueError") возникает, если указанный метод запуска недоступен.
Добавлено в версии 3.4.
`multiprocessing.``get_start_method`(*allow\_none=False*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.get_start_method "Ссылка на это определение")
Возвращает имя метода запуска используемый для запуска процессов.
Если метод начала не был исправлен, и *allow\_none* ложный, то метод начала прикреплен к дефолту, и имя - возвращенный. Если метод запуска не был фиксирован, а *allow\_none* имеет значение true, то `None` имеет значение возвращенный.
возвращает значение может быть `'fork'`, `'spawn'`, `'forkserver'` или `None`. `'fork'` является значением по умолчанию в Unix, а `'spawn'` - значением по умолчанию в Windows.
Добавлено в версии 3.4.
`multiprocessing.``set_executable`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.set_executable "Ссылка на это определение")
Задает путь к Python интерпретатор, который будет использоваться при запуске дочернего процесса. (По умолчанию [`sys.executable`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/sys.html#sys.executable "sys.executable") - используемый). Встраивающие устройства, вероятно, должны будут сделать что-то вроде:
```
set_executable(os.path.join(sys.exec_prefix, 'pythonw.exe'))
```
прежде чем они смогут создавать дочерние процессы.
Изменено в версии 3.4: Теперь поддержанный на Unix, когда метод начала `'spawn'` - используемый.
`multiprocessing.``set_start_method`(*method*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.set_start_method "Ссылка на это определение")
Установите метод, который должен быть используемый, чтобы начать дочерние процессы. *method* может быть `'fork'`, `'spawn'` или `'forkserver'`.
Следует отметить, что это должно вызываться не более одного раза и должно быть защищено внутри `if __name__ == '__main__'` клаузула основного модуля.
Добавлено в версии 3.4.
Примечание
[`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") не содержит аналогов [`threading.active_count()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.active_count "threading.active_count"), [`threading.enumerate()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.enumerate "threading.enumerate"), [`threading.settrace()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.settrace "threading.settrace"), [`threading.setprofile()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.setprofile "threading.setprofile"), [`threading.Timer`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Timer "threading.Timer") или [`threading.local`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.local "threading.local").
### Объекты связи[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id11 "Ссылка на этот заголовок")
Объекты соединения позволяют отправлять и принимать выбираемые объекты или строки. Они могут рассматриваться как связанные сокеты, ориентированные на сообщение.
Объекты соединения обычно создаются с помощью [`Pipe`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Pipe "multiprocessing.Pipe") – см. также раздел [Слушатели и клиенты](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-listeners-clients).
*class* `multiprocessing.connection.``Connection`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection "Ссылка на это определение")
`send`(*obj*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.send "Ссылка на это определение")
Отправьте объект на другой конец соединения, который следует прочитать с помощью команды [`recv()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.recv "multiprocessing.connection.Connection.recv").
Объект должен быть подбираемым. Очень большие огурцы (приблизительно 32 MiB +, хотя это зависит от ОС) могут вызвать исключение [`ValueError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#ValueError "ValueError").
`recv`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.recv "Ссылка на это определение")
Возвращает объект, отправленный с другого конца соединения с помощью команды [`send()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.send "multiprocessing.connection.Connection.send"). Блокируется, пока не будет что получить. Поднимает [`EOFError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#EOFError "EOFError"), если ничего не осталось получить, а другой конец был закрыт.
`fileno`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.fileno "Ссылка на это определение")
Возвращает файл дескриптор или дескриптор используемый по соединению.
`close`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.close "Ссылка на это определение")
Закрыть связь.
Это вызывается автоматически при сборе мусора соединения.
`poll`(\[*timeout*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.poll "Ссылка на это определение")
Возвращает, имеются ли данные, доступные для чтения.
Если *timeout* не указан, то он будет возвращает немедленно. Если *timeout* - число, это указывает максимальное время блокировки в секундах. Если *timeout* `None`, то бесконечное время ожидания равно используемый.
Следует отметить, что несколько объектов соединения могут опрашиваться одновременно с помощью функции [`multiprocessing.connection.wait()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.wait "multiprocessing.connection.wait").
`send_bytes`(*buffer*\[, *offset*\[, *size*\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.send_bytes "Ссылка на это определение")
Отправка байтовых данных из [байтоподобного объекта](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/glossary.html#term-15) в виде полного сообщения.
Если задано значение *offset*, то данные считываются из этой позиции в *buffer*. Если задано значение *size*, то многие байты будут считываться из буфера. Очень большие буферы (приблизительно 32 MiB +, хотя это зависит от ОС) могут вызвать исключение [`ValueError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#ValueError "ValueError")
`recv_bytes`(\[*maxlength*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.recv_bytes "Ссылка на это определение")
Возвращает полное сообщение байтовых данных, отправленное с другого конца соединения в виде строка. Блокируется, пока не будет что получить. Поднимает [`EOFError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#EOFError "EOFError"), если ничего не осталось получить, а другой конец закрылся.
Если задано значение *maxlength*, и сообщение длиннее *maxlength*, то [`OSError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#OSError "OSError") возникает, и соединение будет недоступно для чтения.
Изменено в версии 3.3: Используемая функция поднимает [`IOError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#IOError "IOError"), которое теперь является алиасом [`OSError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#OSError "OSError").
`recv_bytes_into`(*buffer*\[, *offset*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.recv_bytes_into "Ссылка на это определение")
Считывание в *buffer* полного сообщения байтовых данных, отправленных с другого конца соединения, и возвращает количества байтов в сообщении. Блокируется, пока не будет что получить. Поднимает [`EOFError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#EOFError "EOFError"), если ничего не осталось получить, а другой конец был закрыт.
*buffer* должен быть записываемым [байтоподобным объектом](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/glossary.html#term-15). Если задано значение *offset*, то сообщение будет записано в буфер из этой позиции. Смещение должно быть неотрицательным целым числом, меньшим длины *buffer* (в байтах).
Если буфер слишком короткий, то возникает исключение `BufferTooShort` и полное сообщение доступно как `e.args[0]` где `e` - исключение сущность.
Изменено в версии 3.3: Сами объекты соединения теперь могут переноситься между процессами с помощью [`Connection.send()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.send "multiprocessing.connection.Connection.send") и [`Connection.recv()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.recv "multiprocessing.connection.Connection.recv").
Добавлено в версии 3.3: Объекты соединения теперь поддерживают протокол управления контекст - см. раздел [Типы менеджера контекста](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#typecontextmanager). [`__enter__()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#contextmanager.__enter__ "contextmanager.__enter__") возвращает объект подключения, а [`__exit__()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#contextmanager.__exit__ "contextmanager.__exit__") вызывает [`close()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.close "multiprocessing.connection.Connection.close").
Например:
\>\>\>
```
>>> from multiprocessing import Pipe
>>> a, b = Pipe()
>>> a.send([1, 'hello', None])
>>> b.recv()
[1, 'hello', None]
>>> b.send_bytes(b'thank you')
>>> a.recv_bytes()
b'thank you'
>>> import array
>>> arr1 = array.array('i', range(5))
>>> arr2 = array.array('i', [0] * 10)
>>> a.send_bytes(arr1)
>>> count = b.recv_bytes_into(arr2)
>>> assert count == len(arr1) * arr1.itemsize
>>> arr2
array('i', [0, 1, 2, 3, 4, 0, 0, 0, 0, 0])
```
Предупреждение
Метод [`Connection.recv()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.recv "multiprocessing.connection.Connection.recv") автоматически отключает полученные данные, что может быть угрозой безопасности, если вы не можете доверять процессу, отправившему сообщение.
Поэтому, если объект подключения не был создан с помощью `Pipe()`, следует использовать методы [`recv()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.recv "multiprocessing.connection.Connection.recv") и [`send()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.send "multiprocessing.connection.Connection.send") только после выполнения той или иной аутентификации. См. [Ключи аутентификации](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-auth-keys).
Предупреждение
Если процесс погибает, когда он пытается прочитать или записать в пайп, то данные в пайп, вероятно, будут повреждены, поскольку может оказаться невозможным убедиться, где лежат границы сообщения.
### Примитивы синхронизации[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id12 "Ссылка на этот заголовок")
Обычно примитивы синхронизации не так необходимы в многопроцессорной программе, как в многопоточной программе. См. документацию по модулю [`threading`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#module-threading "threading: Потоковый параллелизм.").
Обратите внимание, что можно также создать примитивы синхронизации с помощью объекта менеджера - см. раздел [Менеджеры](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-managers).
*class* `multiprocessing.``Barrier`(*parties*\[, *action*\[, *timeout*\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Barrier "Ссылка на это определение")
Объект барьер: клон [`threading.Barrier`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Barrier "threading.Barrier").
Добавлено в версии 3.3.
*class* `multiprocessing.``BoundedSemaphore`(\[*value*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.BoundedSemaphore "Ссылка на это определение")
Барьерный семафорный объект: близкий аналог [`threading.BoundedSemaphore`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.BoundedSemaphore "threading.BoundedSemaphore").
Существует одиночное отличие от его близкого аналога: первый аргумент его метода `acquire` называется *block*, как это согласуется с [`Lock.acquire()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock.acquire "multiprocessing.Lock.acquire").
Примечание
В Mac OS X это неотличимо от [`Semaphore`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Semaphore "multiprocessing.Semaphore"), потому что `sem_getvalue()` не реализована на этой платформе.
*class* `multiprocessing.``Condition`(\[*lock*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Condition "Ссылка на это определение")
Переменная условия: алиас для [`threading.Condition`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Condition "threading.Condition").
Если задано значение *lock*, то это должен быть объект [`Lock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock "multiprocessing.Lock") или [`RLock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.RLock "multiprocessing.RLock") из [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.").
Изменено в версии 3.3: Добавлен метод [`wait_for()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Condition.wait_for "threading.Condition.wait_for").
*class* `multiprocessing.``Event`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Event "Ссылка на это определение")
Клон [`threading.Event`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Event "threading.Event").
*class* `multiprocessing.``Lock`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock "Ссылка на это определение")
Нерекурсивный объект блокировки: близкий аналог [`threading.Lock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Lock "threading.Lock"). Как только процесс или поток приобрел блокировку, последующие попытки получить ее от любого процесса или поток будут блокироваться до тех пор, пока она не будет освобождена; любой процесс или поток может освободить его. Понятия и поведение [`threading.Lock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Lock "threading.Lock") в том виде, в каком они применяются к потоки, воспроизводятся здесь в [`multiprocessing.Lock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock "multiprocessing.Lock"), как это применимо к процессам или потоки, за исключением отмеченных.
Обратите внимание, что [`Lock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock "multiprocessing.Lock") - на самом деле фабричная функция, какой возвращает сущность `multiprocessing.synchronize.Lock` инициализировал с дефолтом контекст.
[`Lock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock "multiprocessing.Lock") поддерживает протокол [контекстного менеджера](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/glossary.html#term-22) и таким образом может быть используемый в [`with`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/reference/compound_stmts.html#with) инструкции.
`acquire`(*block=True*, *timeout=None*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock.acquire "Ссылка на это определение")
Получить блокировку, блокировку или неблокировку.
Если для аргумента *block* установлено значение `True` (значение по умолчанию), вызов метода будет блокироваться до тех пор, пока блокировка не окажется в разблокированном состояние, а затем будет установлен параметр locked и возвращает `True`. Обратите внимание, что имя этого первого аргумента отличается от имени в [`threading.Lock.acquire()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Lock.acquire "threading.Lock.acquire").
Если для аргумента *block* установлено значение `False`, вызов метода не блокируется. Если блокировка в данный момент находится в заблокированном состояние, возвращает `False`; в противном случае установите блокировку на заблокированный состояние и возвращает `True`.
При вызове с положительным значение с плавающей запятой для *timeout* блок максимум на количество секунд, указанное параметром *timeout*, если блокировка не может быть получена. Просьбы с отрицательным значение для *timeout* эквивалентны *timeout* ноля. Вызовы с *timeout* значение `None` (по умолчанию) устанавливают период тайм-аута как бесконечный. Отметим, что лечение отрицательного или `None` значения для *timeout* отличается от реализованного поведения в [`threading.Lock.acquire()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Lock.acquire "threading.Lock.acquire"). Аргумент *timeout* не имеет практических последствий, если аргумент *block* имеет значение `False` и, таким образом, игнорируется. Возвращает `True` если блокировка была приобретена или `False`, если истек период ожидания.
`release`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock.release "Ссылка на это определение")
Отпустите замок. Это может быть вызвано из любого процесса или поток, а не только из процесса или поток, которые первоначально приобрели блокировку.
Поведение аналогично поведению в [`threading.Lock.release()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Lock.release "threading.Lock.release"), за исключением того, что при вызове на разблокированной блокировке возникает [`ValueError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#ValueError "ValueError").
*class* `multiprocessing.``RLock`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.RLock "Ссылка на это определение")
Объект рекурсивной блокировки: близкий аналог [`threading.RLock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.RLock "threading.RLock"). Рекурсивная блокировка должна быть разблокирована процессом или поток, получившим ее. Как только процесс или поток приобрел рекурсивную блокировку, тот же самый процесс или поток может снова получить ее без блокировки; этот процесс или поток должны выпускать его один раз в каждый раз, когда он был приобретен.
Обратите внимание, что [`RLock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.RLock "multiprocessing.RLock") - на самом деле фабричная функция, какой возвращает сущность `multiprocessing.synchronize.RLock` инициализировал с дефолтом контекст.
[`RLock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.RLock "multiprocessing.RLock") поддерживает протокол [контекстного менеджера](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/glossary.html#term-22) и таким образом может быть используемый в [`with`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/reference/compound_stmts.html#with) инструкции.
`acquire`(*block=True*, *timeout=None*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.RLock.acquire "Ссылка на это определение")
Получить блокировку, блокировку или неблокировку.
При вызове с аргументом *block*, имеющим значение `True`, блокировать до тех пор, пока блокировка не окажется в разблокированном состояние (не принадлежащем какому-либо процессу или поток), пока блокировка уже не принадлежит текущему процессу или поток. Текущий процесс или поток затем получает право собственности на блокировку (если она еще не имеет права собственности), а уровень рекурсии внутри блокировки увеличивается на единицу, что приводит к возвращает значение `True`. Обратите внимание, что в поведении этого первого аргумента существует несколько различий по сравнению с реализацией [`threading.RLock.acquire()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.RLock.acquire "threading.RLock.acquire"), начиная с имени самого аргумента.
При вызове с аргументом *block*, имеющим значение `False`, не блокируйте. Если замок был уже приобретен (и таким образом принадлежит) другим процессом или поток, текущий процесс или поток не берут собственность, и уровень рекурсии в замке не изменен, приведя к возвращает значение `False`. Если блокировка находится в разблокированном состояние, текущий процесс или поток становится владельцем и уровень рекурсии увеличивается, что приводит к возвращает значение `True`.
Использование и поведение аргумента *timeout* такие же, как и в [`Lock.acquire()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock.acquire "multiprocessing.Lock.acquire"). Обратите внимание, что некоторые из этих поведений *timeout* отличаются от реализованных поведений в [`threading.RLock.acquire()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.RLock.acquire "threading.RLock.acquire").
`release`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.RLock.release "Ссылка на это определение")
Разблокируйте блокировку, уменьшая уровень рекурсии. Если после уменьшения уровень рекурсии равен нулю, сбросьте блокировку на разблокированную (не принадлежащую какому-либо процессу или поток) и если какие-либо другие процессы или потоки заблокированы в ожидании разблокировки блокировки, разрешите выполнение только одного из них. Если после уменьшения уровень рекурсии остается ненулевым, блокировка остается заблокированной и принадлежит вызывающему процессу или поток.
Только назовите этот метод, когда процесс запроса или поток будут владеть замком. [`AssertionError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#AssertionError "AssertionError") поднят, если этот метод называют процесс или поток кроме владельца или если замок находится в незапертом (ненаходящемся в собственности) состояние. Обратите внимание, что тип исключения, вызванного в этой ситуации, отличается от реализованного поведения в [`threading.RLock.release()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.RLock.release "threading.RLock.release").
*class* `multiprocessing.``Semaphore`(\[*value*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Semaphore "Ссылка на это определение")
Семафорный объект: близкий аналог [`threading.Semaphore`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Semaphore "threading.Semaphore").
Существует одиночное отличие от его близкого аналога: первый аргумент его метода `acquire` называется *block*, как это согласуется с [`Lock.acquire()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock.acquire "multiprocessing.Lock.acquire").
Примечание
В Mac OS X `sem_timedwait` не поддерживается, поэтому вызов `acquire()` с тайм-аутом будет эмулировать поведение этой функции с помощью спящего цикла.
Примечание
Если сигнал SIGINT, сгенерированный `Ctrl-C`, прибудет, в то время как главный поток заблокирован требованием к `BoundedSemaphore.acquire()`, [`Lock.acquire()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock.acquire "multiprocessing.Lock.acquire"), [`RLock.acquire()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.RLock.acquire "multiprocessing.RLock.acquire"), `Semaphore.acquire()`, `Condition.acquire()` или `Condition.wait()` тогда, требование будет немедленно прервано, и [`KeyboardInterrupt`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#KeyboardInterrupt "KeyboardInterrupt") будет поднят.
Это отличается от поведения [`threading`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#module-threading "threading: Потоковый параллелизм."), где SIGINT будет игнорироваться во время выполнения эквивалентных блокирующих вызовов.
Примечание
Некоторые функциональные возможности этого пакета требуют функциональной реализации общего семафора в операционной системе хоста. Без него модуль `multiprocessing.synchronize` будет отключен, и попытки его импорта приведут к появлению [`ImportError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#ImportError "ImportError"). Дополнительные сведения см. в разделе [bpo-3770](https://bugs.python.org/issue3770).
### Разделенные объекты [`ctypes`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/ctypes.html#module-ctypes "ctypes: Python библиотека внешних функций.")[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#ctypes "Ссылка на этот заголовок")
С помощью общей памяти можно создавать общие объекты, которые могут наследоваться дочерними процессами.
`multiprocessing.``Value`(*typecode\_or\_type*, *\*args*, *lock=True*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Value "Ссылка на это определение")
Возвращает объект [`ctypes`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/ctypes.html#module-ctypes "ctypes: Python библиотека внешних функций."), выделенный из общей памяти. По умолчанию возвращает значение фактически является синхронизированной оболочкой для объекта. К самому объекту можно получить доступ через *value* атрибут [`Value`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Value "multiprocessing.Value").
*typecode\_or\_type* определяет тип объекта возвращенный: это - или тип ctypes или один символ typecode доброго используемый модулем [`array`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/array.html#module-array "array: Пространственно-эффективные массивы типизированных числовых значений."). *\*args* передан конструктору для типа.
Если *lock* равно `True` (по умолчанию), создается новый объект рекурсивной блокировки для синхронизации доступа к значение. Если *lock* является объектом [`Lock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock "multiprocessing.Lock") или [`RLock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.RLock "multiprocessing.RLock"), то это будет используемый для синхронизации доступа к значение. Если *lock* будет `False` тогда, то доступ к объекту возвращенный не будет автоматически защищен замком, таким образом, это не обязательно будет «безопасно от процесса».
Операции как `+=`, которые включают прочитанный и пишут, не атомные. Так что, если для сущность, вы хотите атомарно увеличить общий значение это недостаточно, чтобы просто сделать:
```
counter.value += 1
```
Предполагая, что связанная блокировка является рекурсивной (что по умолчанию), можно сделать:
```
with counter.get_lock():
counter.value += 1
```
Обратите внимание, что *lock* является только ключевым аргументом.
`multiprocessing.``Array`(*typecode\_or\_type*, *size\_or\_initializer*, *\**, *lock=True*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Array "Ссылка на это определение")
Возвращает массив ctypes, выделенный из общей памяти. По умолчанию возвращает значение фактически является синхронизированной обёрткой для массива.
*typecode\_or\_type* определяет тип элементов множества возвращенный: это - или тип ctypes или один символ typecode доброго используемый модулем [`array`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/array.html#module-array "array: Пространственно-эффективные массивы типизированных числовых значений."). Если *size\_or\_initializer* является целым числом, то он определяет длину массива, и массив будет первоначально обнулен. Иначе *size\_or\_initializer* - последовательность, которая является используемый, чтобы инициализировать множество и чья длина определяет длину множества.
Если *lock* равно `True` (по умолчанию), создается новый объект блокировки для синхронизации доступа к значение. Если *lock* является объектом [`Lock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock "multiprocessing.Lock") или [`RLock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.RLock "multiprocessing.RLock"), то это будет используемый для синхронизации доступа к значение. Если *lock* будет `False` тогда, то доступ к объекту возвращенный не будет автоматически защищен замком, таким образом, это не обязательно будет «безопасно от процесса».
Обратите внимание, что *lock* - ключевой только аргумент.
Обратите внимание, что у множества [`ctypes.c_char`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/ctypes.html#ctypes.c_char "ctypes.c_char") есть *value* и *raw* атрибуты, которые позволяют использовать его, чтобы сохранить и восстановить строки.
#### Модуль [`multiprocessing.sharedctypes`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.sharedctypes "multiprocessing.sharedctypes: Аллоцировать объекты ctypes из общей памяти.")[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.sharedctypes "Ссылка на этот заголовок")
Модуль [`multiprocessing.sharedctypes`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.sharedctypes "multiprocessing.sharedctypes: Аллоцировать объекты ctypes из общей памяти.") предоставляет функции для выделения объектов [`ctypes`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/ctypes.html#module-ctypes "ctypes: Python библиотека внешних функций.") из общей памяти, которые могут быть унаследованы дочерними процессами.
Примечание
Хотя можно сохранить указатель в общей памяти, помните, что это относится к расположению в адресном пространстве конкретного процесса. Однако указатель, вероятно, недействителен в контекст второго процесса, и попытка отсоединить указатель от второго процесса может вызвать сбой.
`multiprocessing.sharedctypes.``RawArray`(*typecode\_or\_type*, *size\_or\_initializer*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.sharedctypes.RawArray "Ссылка на это определение")
Возвращает массив ctypes, выделенный из общей памяти.
*typecode\_or\_type* определяет тип элементов множества возвращенный: это - или тип ctypes или один символ typecode доброго используемый модулем [`array`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/array.html#module-array "array: Пространственно-эффективные массивы типизированных числовых значений."). Если *size\_or\_initializer* является целым числом, то он определяет длину массива, и массив будет первоначально обнулен. Иначе *size\_or\_initializer* - последовательность, которая является используемый, чтобы инициализировать множество и чья длина определяет длину множества.
Обратите внимание, что настройка и получение элемента потенциально неатомны - вместо этого используйте команду [`Array()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.sharedctypes.Array "multiprocessing.sharedctypes.Array"), чтобы убедиться, что доступ автоматически синхронизирован с помощью блокировки.
`multiprocessing.sharedctypes.``RawValue`(*typecode\_or\_type*, *\*args*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.sharedctypes.RawValue "Ссылка на это определение")
Возвращает объект ctypes, выделенный из общей памяти.
*typecode\_or\_type* определяет тип объекта возвращенный: это - или тип ctypes или один символ typecode доброго используемый модулем [`array`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/array.html#module-array "array: Пространственно-эффективные массивы типизированных числовых значений."). *\*args* передан конструктору для типа.
Обратите внимание, что настройка и получение значение потенциально неатомны - вместо этого используйте [`Value()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.sharedctypes.Value "multiprocessing.sharedctypes.Value"), чтобы убедиться, что доступ автоматически синхронизирован с помощью блокировки.
Обратите внимание, что массив [`ctypes.c_char`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/ctypes.html#ctypes.c_char "ctypes.c_char") имеет `value` и `raw` атрибуты, которые позволяют использовать его для хранения и извлечения строки - см. документацию для [`ctypes`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/ctypes.html#module-ctypes "ctypes: Python библиотека внешних функций.").
`multiprocessing.sharedctypes.``Array`(*typecode\_or\_type*, *size\_or\_initializer*, *\**, *lock=True*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.sharedctypes.Array "Ссылка на это определение")
То же как [`RawArray()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.sharedctypes.RawArray "multiprocessing.sharedctypes.RawArray") за исключением того, что в зависимости от значение *lock* безопасная от процесса обертка синхронизации может быть возвращенный вместо сырья ctypes множество.
Если *lock* равно `True` (по умолчанию), создается новый объект блокировки для синхронизации доступа к значение. Если *lock* является объектом [`Lock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock "multiprocessing.Lock") или [`RLock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.RLock "multiprocessing.RLock"), то это будет используемый для синхронизации доступа к значение. Если *lock* будет `False` тогда, то доступ к объекту возвращенный не будет автоматически защищен замком, таким образом, это не обязательно будет «безопасно от процесса».
Обратите внимание, что *lock* является толко ключевым аргументом.
`multiprocessing.sharedctypes.``Value`(*typecode\_or\_type*, *\*args*, *lock=True*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.sharedctypes.Value "Ссылка на это определение")
То же как [`RawValue()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.sharedctypes.RawValue "multiprocessing.sharedctypes.RawValue") за исключением того, что в зависимости от значение *lock* безопасная от процесса обертка синхронизации может быть возвращенный вместо сырья ctypes объект.
Если *lock* равно `True` (по умолчанию), создается новый объект блокировки для синхронизации доступа к значение. Если *lock* является объектом [`Lock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Lock "multiprocessing.Lock") или [`RLock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.RLock "multiprocessing.RLock"), то это будет используемый для синхронизации доступа к значение. Если *lock* будет `False` тогда, то доступ к объекту возвращенный не будет автоматически защищен замком, таким образом, это не обязательно будет «безопасно от процесса».
Обратите внимание, что *lock* является только ключевым аргументом.
`multiprocessing.sharedctypes.``copy`(*obj*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.sharedctypes.copy "Ссылка на это определение")
Возвращает объект ctypes, выделенный из общей памяти, который является копией объекта ctypes *obj*.
`multiprocessing.sharedctypes.``synchronized`(*obj*\[, *lock*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.sharedctypes.synchronized "Ссылка на это определение")
Возвращает безопасный для процесса объект-обертка для объекта ctypes, который использует *lock* для синхронизации доступа. Если *lock* имеет значение `None` (по умолчанию), то объект [`multiprocessing.RLock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.RLock "multiprocessing.RLock") создается автоматически.
Синхронизированная обертка будет иметь два метода в дополнение к методам обертываемого объекта: `get_obj()` возвращает обертываемый объект и `get_lock()` возвращает блокируемый объект используемый для синхронизации.
Обратите внимание, что доступ к объекту ctypes через оболочку может быть намного медленнее, чем доступ к объекту raw ctypes.
Изменено в версии 3.5: Синхронизированные объекты поддерживают протокол [менеджера контекста](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/glossary.html#term-22).
В приведенной ниже таблице сравнивается синтаксис создания общих объектов ctypes из общей памяти с синтаксисом обычных ctypes. (В таблице `MyStruct` представлена некоторая подкласс [`ctypes.Structure`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/ctypes.html#ctypes.Structure "ctypes.Structure").
| ctypes | sharedctypes используя тип | sharedctypes используя typecode |
|---|---|---|
| c\_double(2.4) | RawValue(c\_double, 2.4) | RawValue(„d“, 2.4) |
| MyStruct(4, 6) | RawValue(MyStruct, 4, 6) | |
| (c\_short \* 7)() | RawArray(c\_short, 7) | RawArray(„h“, 7) |
| (c\_int \* 3)(9, 2, 8) | RawArray(c\_int, (9, 2, 8)) | RawArray(„i“, (9, 2, 8)) |
Ниже приведен пример, когда ряд объектов ctypes изменяется дочерним процессом:
```
from multiprocessing import Process, Lock
from multiprocessing.sharedctypes import Value, Array
from ctypes import Structure, c_double
class Point(Structure):
_fields_ = [('x', c_double), ('y', c_double)]
def modify(n, x, s, A):
n.value **= 2
x.value **= 2
s.value = s.value.upper()
for a in A:
a.x **= 2
a.y **= 2
if __name__ == '__main__':
lock = Lock()
n = Value('i', 7)
x = Value(c_double, 1.0/3.0, lock=False)
s = Array('c', b'hello world', lock=lock)
A = Array(Point, [(1.875,-6.25), (-5.75,2.0), (2.375,9.5)], lock=lock)
p = Process(target=modify, args=(n, x, s, A))
p.start()
p.join()
print(n.value)
print(x.value)
print(s.value)
print([(a.x, a.y) for a in A])
```
Результаты напечатаны:
```
49
0.1111111111111111
HELLO WORLD
[(3.515625, 39.0625), (33.0625, 4.0), (5.640625, 90.25)]
```
### Менеджеры[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-managers "Ссылка на этот заголовок")
Менеджеры предоставляют способ создания данных, которые могут совместно использоваться различными процессами, включая совместное использование по сети между процессами, работающими на разных машинах. Объект-менеджер управляет серверным процессом, который управляет *shared objects*. Другие процессы могут обращаться к общим объектам с помощью прокси.
`multiprocessing.``Manager`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.sharedctypes.multiprocessing.Manager "Ссылка на это определение")
Возвращает начатый объект [`SyncManager`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager "multiprocessing.managers.SyncManager"), который может быть используемый для разделения объектов между процессами. Объект менеджера возвращенный соответствует порожденному дочернему процессу и имеет методы, которые создадут общие объекты и соответствующие возвращаемое прокси.
Процессы менеджера будут остановлены сразу после сбора мусора или завершения родительского процесса. Классы менеджера определяются в модуле [`multiprocessing.managers`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.managers "multiprocessing.managers: Обмен данными между процессами с общими объектами."):
*class* `multiprocessing.managers.``BaseManager`(\[*address*\[, *authkey*\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager "Ссылка на это определение")
Создайте объект BaseManager.
После создания необходимо вызвать [`start()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager.start "multiprocessing.managers.BaseManager.start") или `get_server().serve_forever()`, чтобы гарантировать, что объект менеджера ссылается на запущенный процесс менеджера.
*address* - адрес, по которому процесс менеджера прослушивает новые подключения. Если *address* `None`, то выбирается произвольная.
*authkey* - ключ идентификации, который будет используемый, чтобы проверить законность поступающих связей с процессом сервера. Если *authkey* - `None` тогда, `current_process().authkey` - используемый. В противном случае *authkey* является используемый и должен быть байтом строка.
`start`(\[*initializer*\[, *initargs*\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager.start "Ссылка на это определение")
Начните подпроцессы, чтобы начать менеджера. Если *initializer* не является `None`, то подпроцессы вызовет `initializer(*initargs)` при запуске.
`get_server`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager.get_server "Ссылка на это определение")
Возвращает объект `Server`, представляющий фактический сервер под управлением менеджера. Объект `Server` поддерживает метод `serve_forever()`:
\>\>\>
```
>>> from multiprocessing.managers import BaseManager
>>> manager = BaseManager(address=('', 50000), authkey=b'abc')
>>> server = manager.get_server()
>>> server.serve_forever()
```
`Server` дополнительно содержит [`address`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager.address "multiprocessing.managers.BaseManager.address") атрибут.
`connect`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager.connect "Ссылка на это определение")
Подключить объект локального менеджера к процессу удаленного менеджера:
\>\>\>
```
>>> from multiprocessing.managers import BaseManager
>>> m = BaseManager(address=('127.0.0.1', 50000), authkey=b'abc')
>>> m.connect()
```
`shutdown`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager.shutdown "Ссылка на это определение")
Остановить процесс используемый менеджером. Это только доступно, если [`start()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager.start "multiprocessing.managers.BaseManager.start") был используемый, чтобы начать процесс сервера.
Это можно вызвать несколько раз.
`register`(*typeid*\[, *callable*\[, *proxytype*\[, *exposed*\[, *method\_to\_typeid*\[, *create\_method*\]\]\]\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager.register "Ссылка на это определение")
classmethod, который может быть используемый для регистрации типа или подлежащий выкупу с классом менеджера.
*typeid* - «идентификатор типа», который является используемый, чтобы определить особый тип общего объекта. Это должно быть строка.
*callable* является вызываемым используемый для создания объектов для этого идентификатора типа. Если диспетчер сущность будет подключен к серверу с помощью метода [`connect()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager.connect "multiprocessing.managers.BaseManager.connect") или если аргумент *create\_method* имеет значение `False`, его можно оставить как `None`.
*proxytype* является подкласс [`BaseProxy`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseProxy "multiprocessing.managers.BaseProxy"), который используемый для создания прокси для общих объектов с этим *typeid*. Если `None`, то класс прокси создается автоматически.
*exposed* - используемый, чтобы определить последовательность вызова метода, которые прокси для этого typeid нужно разрешить доступу, используя [`BaseProxy._callmethod()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseProxy._callmethod "multiprocessing.managers.BaseProxy._callmethod"). (Если *exposed* - `None` тогда, `proxytype._exposed_` - используемый вместо этого, если он существует.) в случае, если не указан список разоблаченных объектов, будут доступны все «публичные методы» общего объекта. (Здесь «метод публичный» означает любой атрибут, у которого есть метод [`__call__()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/reference/datamodel.html#object.__call__ "object.__call__") и чьё имя не начинается с `'_'`.)
*method\_to\_typeid* - отображение используемый, чтобы определить тип возвращает тех выставленных методов, которые должны возвращает прокси. Это наносит на карту названия метода к typeid строки. (Если *method\_to\_typeid* - `None` тогда, `proxytype._method_to_typeid_` - используемый вместо этого, если он существует.) Если вызов метода не будет ключом этого отображения или если отображение будет `None` тогда объект, то возвращенный методом будет скопирован значение.
*create\_method* определяет, должен ли метод быть создан с именем *typeid*, который может быть используемый, чтобы сказать процессу сервера создавать новый общий объект и возвращает прокси для него. По умолчанию это значение равно `True`.
[`BaseManager`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager "multiprocessing.managers.BaseManager") сущности также имеют одно свойство только для чтения:
`address`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager.address "Ссылка на это определение")
Адрес, используемый менеджером.
Изменено в версии 3.3: Объекты менеджера поддерживают протокол управления контекст - см. раздел [Типы менеджера контекста](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#typecontextmanager). [`__enter__()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#contextmanager.__enter__ "contextmanager.__enter__") запускает процесс сервера (если он еще не запущен), а затем возвращает объект диспетчера. [`__exit__()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#contextmanager.__exit__ "contextmanager.__exit__") вызовы [`shutdown()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager.shutdown "multiprocessing.managers.BaseManager.shutdown").
В предыдущих версиях [`__enter__()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#contextmanager.__enter__ "contextmanager.__enter__") не запускал серверный процесс диспетчера, если он еще не был запущен.
*class* `multiprocessing.managers.``SyncManager`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager "Ссылка на это определение")
Подкласс [`BaseManager`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager "multiprocessing.managers.BaseManager"), который может быть используемый для синхронизации процессов. Объекты этого типа возвращенный `multiprocessing.Manager()`.
Его методы обычно создают и возвращает [Прокси объекты](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-proxy-objects) для многих типы данных используемый, которые будут синхронизированы через процессы. Это, в частности, включает общие списки и словари.
`Barrier`(*parties*\[, *action*\[, *timeout*\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.Barrier "Ссылка на это определение")
Создание общего объекта [`threading.Barrier`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Barrier "threading.Barrier") и возвращает прокси для него.
Добавлено в версии 3.3.
`BoundedSemaphore`(\[*value*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.BoundedSemaphore "Ссылка на это определение")
Создание общего объекта [`threading.BoundedSemaphore`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.BoundedSemaphore "threading.BoundedSemaphore") и возвращает прокси для него.
`Condition`(\[*lock*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.Condition "Ссылка на это определение")
Создание общего объекта [`threading.Condition`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Condition "threading.Condition") и возвращает прокси для него.
Если задано значение *lock*, то оно должно быть прокси для объекта [`threading.Lock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Lock "threading.Lock") или [`threading.RLock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.RLock "threading.RLock").
Изменено в версии 3.3: Добавлен метод [`wait_for()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Condition.wait_for "threading.Condition.wait_for").
`Event`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.Event "Ссылка на это определение")
Создание общего объекта [`threading.Event`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Event "threading.Event") и возвращает прокси для него.
`Lock`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.Lock "Ссылка на это определение")
Создание общего объекта [`threading.Lock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Lock "threading.Lock") и возвращает прокси для него.
`Namespace`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.Namespace "Ссылка на это определение")
Создание общего объекта [`Namespace`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.Namespace "multiprocessing.managers.Namespace") и возвращает прокси для него.
`Queue`(\[*maxsize*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.Queue "Ссылка на это определение")
Создание общего объекта [`queue.Queue`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/queue.html#queue.Queue "queue.Queue") и возвращает прокси для него.
`RLock`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.RLock "Ссылка на это определение")
Создание общего объекта [`threading.RLock`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.RLock "threading.RLock") и возвращает прокси для него.
`Semaphore`(\[*value*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.Semaphore "Ссылка на это определение")
Создание общего объекта [`threading.Semaphore`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#threading.Semaphore "threading.Semaphore") и возвращает прокси для него.
`Array`(*typecode*, *sequence*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.Array "Ссылка на это определение")
Создайте массив и возвращает прокси-сервер для него.
`Value`(*typecode*, *value*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.Value "Ссылка на это определение")
Создайте объект с возможностью записи `value` атрибут и возвращает прокси для него.
`dict`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.dict "Ссылка на это определение")
`dict`(*mapping*)
`dict`(*sequence*)
Создание общего объекта [`dict`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.dict "multiprocessing.managers.SyncManager.dict") и возвращает прокси для него.
`list`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager.list "Ссылка на это определение")
`list`(*sequence*)
Создание общего объекта [`list`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#list "list") и возвращает прокси для него.
Изменено в версии 3.6: Общие объекты могут быть вложены. Например, объект общего контейнера, такой как общий список, может содержать другие общие объекты, которые будут управляться и синхронизироваться [`SyncManager`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager "multiprocessing.managers.SyncManager").
*class* `multiprocessing.managers.``Namespace`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.Namespace "Ссылка на это определение")
Тип, который может регистрироваться в [`SyncManager`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.SyncManager "multiprocessing.managers.SyncManager").
Объект пространства имен не имеет публичных методов, но содержит записываемые атрибуты. Его представление показывает значения его атрибутов.
Однако при использовании прокси для объекта пространства имен атрибут, начинающийся с `'_'`, будет атрибут прокси, а не атрибут ссылки:
\>\>\>
```
>>> manager = multiprocessing.Manager()
>>> Global = manager.Namespace()
>>> Global.x = 10
>>> Global.y = 'hello'
>>> Global._z = 12.3 # это атрибут прокси
>>> print(Global)
Namespace(x=10, y='hello')
```
#### Настраиваемые менеджеры[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id14 "Ссылка на этот заголовок")
Для создания собственного менеджера создается подкласс [`BaseManager`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager "multiprocessing.managers.BaseManager") и используется классметод [`register()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager.register "multiprocessing.managers.BaseManager.register") для регистрации новых типов или вызываемых объектов в классе менеджера. Например:
```
from multiprocessing.managers import BaseManager
class MathsClass:
def add(self, x, y):
return x + y
def mul(self, x, y):
return x * y
class MyManager(BaseManager):
pass
MyManager.register('Maths', MathsClass)
if __name__ == '__main__':
with MyManager() as manager:
maths = manager.Maths()
print(maths.add(4, 3)) # prints 7
print(maths.mul(7, 8)) # prints 56
```
#### Использование удаленного менеджера[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id15 "Ссылка на этот заголовок")
Можно запускать сервер менеджера на одной машине и использовать его клиентами с других машин (при условии, что соответствующие брандмауэры разрешают это).
Выполнение следующих команд создает сервер для одной общей очереди, к которой могут иметь доступ удаленные клиенты:
\>\>\>
```
>>> from multiprocessing.managers import BaseManager
>>> from queue import Queue
>>> queue = Queue()
>>> class QueueManager(BaseManager): pass
>>> QueueManager.register('get_queue', callable=lambda:queue)
>>> m = QueueManager(address=('', 50000), authkey=b'abracadabra')
>>> s = m.get_server()
>>> s.serve_forever()
```
Один клиент может получить доступ к серверу следующим образом:
\>\>\>
```
>>> from multiprocessing.managers import BaseManager
>>> class QueueManager(BaseManager): pass
>>> QueueManager.register('get_queue')
>>> m = QueueManager(address=('foo.bar.org', 50000), authkey=b'abracadabra')
>>> m.connect()
>>> queue = m.get_queue()
>>> queue.put('hello')
```
Его также может использовать другой клиент:
\>\>\>
```
>>> from multiprocessing.managers import BaseManager
>>> class QueueManager(BaseManager): pass
>>> QueueManager.register('get_queue')
>>> m = QueueManager(address=('foo.bar.org', 50000), authkey=b'abracadabra')
>>> m.connect()
>>> queue = m.get_queue()
>>> queue.get()
'hello'
```
Локальные процессы также могут обращаться к этой очереди, используя код сверху на клиенте для удаленного доступа к ней:
\>\>\>
```
>>> from multiprocessing import Process, Queue
>>> from multiprocessing.managers import BaseManager
>>> class Worker(Process):
... def __init__(self, q):
... self.q = q
... super(Worker, self).__init__()
... def run(self):
... self.q.put('local hello')
...
>>> queue = Queue()
>>> w = Worker(queue)
>>> w.start()
>>> class QueueManager(BaseManager): pass
...
>>> QueueManager.register('get_queue', callable=lambda: queue)
>>> m = QueueManager(address=('', 50000), authkey=b'abracadabra')
>>> s = m.get_server()
>>> s.serve_forever()
```
### Прокси объекты[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-proxy-objects "Ссылка на этот заголовок")
Прокси - объект, какой *относится* к общему объекту, который живет (по- видимому), в другом процессе. Говорят, что общий объект является *ссылкой* прокси. Несколько прокси-объектов могут иметь один и тот же ссылочный объект.
Прокси-объект содержат методы, которые вызывают соответствующие методы его ссылки (хотя не каждый метод ссылки обязательно будет доступен через прокси). Таким образом, прокси может быть используемый так же, как его референт:
\>\>\>
```
>>> from multiprocessing import Manager
>>> manager = Manager()
>>> l = manager.list([i*i for i in range(10)])
>>> print(l)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> print(repr(l))
<ListProxy object, typeid 'list' at 0x...>
>>> l[4]
16
>>> l[2:5]
[4, 9, 16]
```
Заметьте, что применение `str()` прокси будет возвращает представление референта, тогда как применение [`repr()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/functions.html#repr "repr") будет возвращает представление прокси.
Важной особенностью прокси-объектов является то, что они могут быть переданы между процессами. Таким образом, референт может содержать [Прокси объекты](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-proxy-objects). Это разрешает вложение этих управляемых списков, словари и другого [Прокси объекты](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-proxy-objects):
\>\>\>
```
>>> a = manager.list()
>>> b = manager.list()
>>> a.append(b) # ссылка a теперь содержит ссылку b
>>> print(a, b)
[<ListProxy object, typeid 'list' at ...>] []
>>> b.append('hello')
>>> print(a[0], b)
['hello'] ['hello']
```
Аналогично, прокси словарь и списка могут быть вложены друг в друга:
\>\>\>
```
>>> l_outer = manager.list([ manager.dict() for i in range(2) ])
>>> d_first_inner = l_outer[0]
>>> d_first_inner['a'] = 1
>>> d_first_inner['b'] = 2
>>> l_outer[1]['c'] = 3
>>> l_outer[1]['z'] = 26
>>> print(l_outer[0])
{'a': 1, 'b': 2}
>>> print(l_outer[1])
{'c': 3, 'z': 26}
```
Если стандартные (не прокси) [`list`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#list "list") или `dict` объекты содержатся в ссылке, изменения этих изменяемых значения не будут распространяться через менеджер, поскольку прокси не может знать, когда изменятся содержащиеся в них значения. Однако хранение значение в контейнерном прокси (который вызывает `__setitem__` на объекте по доверенности) действительно размножается через менеджера и так эффективно изменить такой предмет, можно было повторно назначить измененный значение контейнерному прокси:
```
# создать список прокси и добавить изменяемый объект (словарь)
lproxy = manager.list()
lproxy.append({})
# теперь изменяемый словарь
d = lproxy[0]
d['a'] = 1
d['b'] = 2
# на этом этапе изменения d еще не синхронизируются, но при обновлении словаря
# прокси уведомляется об изменении
lproxy[0] = d
```
Этот подход, возможно, менее удобен, чем использование вложенных [Прокси объекты](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-proxy-objects) в большинстве случаев использования, но также демонстрирует уровень управления синхронизацией.
Примечание
Прокси-типы в [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") не поддерживают сравнения по значение. Итак, для сущность у нас есть:
\>\>\>
```
>>> manager.list([1,2,3]) == [1,2,3]
False
```
Вместо этого следует использовать копию ссылки при проведении сравнений.
*class* `multiprocessing.managers.``BaseProxy`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseProxy "Ссылка на это определение")
Объекты по доверенности - сущности подклассы [`BaseProxy`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseProxy "multiprocessing.managers.BaseProxy").
`_callmethod`(*methodname*\[, *args*\[, *kwds*\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseProxy._callmethod "Ссылка на это определение")
Вызов и возвращает результата метода ссылки прокси.
Если `proxy` - прокси, ссылочным элементом которого является `obj`, то выражение:
```
proxy._callmethod(methodname, args, kwds)
```
вычислит выражение:
```
getattr(obj, methodname)(*args, **kwds)
```
в процессе менеджере.
возвращенный значение будет копией результата вызова или прокси для нового общего объекта - см. документацию для аргумента *method\_to\_typeid* [`BaseManager.register()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseManager.register "multiprocessing.managers.BaseManager.register").
Если в результате вызова возникает исключение, то вызов повторно инициируется функцией [`_callmethod()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseProxy._callmethod "multiprocessing.managers.BaseProxy._callmethod"). Если в процессе менеджера возникает другое исключение, оно преобразуется в исключение `RemoteError` и инициируется [`_callmethod()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseProxy._callmethod "multiprocessing.managers.BaseProxy._callmethod").
Обратите внимание, в частности, на то, что исключение будет создано, если *methodname* не было *exposed*.
Пример использования [`_callmethod()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseProxy._callmethod "multiprocessing.managers.BaseProxy._callmethod"):
\>\>\>
```
>>> l = manager.list(range(10))
>>> l._callmethod('__len__')
10
>>> l._callmethod('__getitem__', (slice(2, 7),)) # equivalent to l[2:7]
[2, 3, 4, 5, 6]
>>> l._callmethod('__getitem__', (20,)) # equivalent to l[20]
Traceback (most recent call last):
...
IndexError: list index out of range
```
`_getvalue`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseProxy._getvalue "Ссылка на это определение")
Возвращает копию референта.
Если референт не может быть выбран, это вызовет исключение.
`__repr__`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseProxy.__repr__ "Ссылка на это определение")
Возвращает представление прокси-объекта.
`__str__`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.managers.BaseProxy.__str__ "Ссылка на это определение")
Возвращает представление референта.
#### Очистка[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id17 "Ссылка на этот заголовок")
Объект по доверенности использует weakref колбэк так, чтобы, когда это собрало мусор, он вычеркнул из списка себя от менеджера, который владеет его референтом.
Общий объект удаляется из процесса диспетчера, если на него больше не ссылается ни один прокси.
### Процессные пулы[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.pool "Ссылка на этот заголовок")
Можно создать пул процессов, который будет выполнять задачи, переданные ему с классом [`Pool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "multiprocessing.pool.Pool").
*class* `multiprocessing.pool.``Pool`(\[*processes*\[, *initializer*\[, *initargs*\[, *maxtasksperchild*\[, *context*\]\]\]\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "Ссылка на это определение")
Объект пула процессов, который управляет пулом рабочих процессов, в который могут отправляться задания. Он поддерживает асинхронные результаты с тайм-аутами и колбэки и имеет параллельную реализацию карты.
*processes* - количество используемых рабочих процессов. Если *processes* `None`, то число возвращенный по [`os.cpu_count()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/os.html#os.cpu_count "os.cpu_count") равно используемый.
Если *initializer* не является `None`, то каждый рабочий процесс будет вызывать `initializer(*initargs)` при запуске.
*maxtasksperchild* - количество задач, которые рабочий процесс может выполнить до выхода и замены новым рабочим процессом для освобождения неиспользуемых ресурсов. Дефолт *maxtasksperchild* - `None`, что означает процессы рабочего, будет жить пока бассейн.
*context* может быть используемый, чтобы определить контекст используемый для старта процессов рабочего. Обычно пул создается с помощью функции `multiprocessing.Pool()` или метода [`Pool()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "multiprocessing.pool.Pool") объекта контекст. В обоих случаях *context* устанавливается соответствующим образом.
Следует отметить, что методы объекта пула должны вызываться только процессом, создавшим пул.
Предупреждение
[`multiprocessing.pool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.pool "multiprocessing.pool: Создать пулы процессов.") объекты имеют внутренние ресурсы, которыми необходимо правильно управлять (как и любой другой ресурс), используя пул в качестве менеджера контекст или вызывая [`close()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.close "multiprocessing.pool.Pool.close") и [`terminate()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.terminate "multiprocessing.pool.Pool.terminate") вручную. Неспособность сделать это может привести к зависанию процесса при завершении.
Обратите внимание, что это **не верно**, чтобы полагаться на сборщик мусора, чтобы уничтожить пул, так как CPython не гарантирует, что финализатор пула будет вызван (см. [`object.__del__()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/reference/datamodel.html#object.__del__ "object.__del__") для получения дополнительной информации).
Добавлено в версии 3.2: *maxtasksperchild*
Добавлено в версии 3.4: *context*
Примечание
Рабочие процессы внутри [`Pool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "multiprocessing.pool.Pool") обычно работают в течение всей продолжительности рабочей очереди пула. Частый шаблон, встречающийся в других системах (таких как Apache, mod\_wsgi и т.д.) для освобождения ресурсов, находящихся в распоряжении работников, заключается в том, чтобы позволить работнику в пуле выполнить только определенный объем работы перед выходом, очисткой и новым процессом, который должен заменить старый. Аргумент *maxtasksperchild* [`Pool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "multiprocessing.pool.Pool") предоставляет эту возможность конечному пользователю.
`apply`(*func*\[, *args*\[, *kwds*\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.apply "Ссылка на это определение")
Вызовите *func* с аргументами *args* и ключевой аргументы *kwds*. Он блокируется до тех пор, пока результат не будет готов. Учитывая эти блоки, [`apply_async()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.apply_async "multiprocessing.pool.Pool.apply_async") лучше подходит для выполнения работы параллельно. Кроме того, *func* выполняется только в одном из работников пула.
`apply_async`(*func*\[, *args*\[, *kwds*\[, *callback*\[, *error\_callback*\]\]\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.apply_async "Ссылка на это определение")
Вариант метода [`apply()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.apply "multiprocessing.pool.Pool.apply"), который возвращает объект [`AsyncResult`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.AsyncResult "multiprocessing.pool.AsyncResult").
Если задан параметр *callback*, то он должен быть вызываемым и принимать один аргумент. То, когда результат становится готовым *callback*, применено к нему, это - то, если неудавшееся требование, в этом случае *error\_callback* не применен вместо этого.
Если задан параметр *error\_callback*, то он должен быть вызываемым и принимать один аргумент. Если целевая функция терпит неудачу, то *error\_callback* называют за исключением сущность.
Обратные вызовы должны быть завершены немедленно, поскольку в противном случае поток, обрабатывающая результаты, будет заблокирована.
`map`(*func*, *iterable*\[, *chunksize*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.map "Ссылка на это определение")
Параллельный эквивалент встроенной функции [`map()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/functions.html#map "map") (однако он поддерживает только один аргумент *iterable* для нескольких итерабелей см. [`starmap()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.starmap "multiprocessing.pool.Pool.starmap")). Он блокируется до тех пор, пока результат не будет готов.
Этот метод разбивает итабль на несколько чанки, которые он передает в пул процессов как отдельные задачи. (Приблизительный) размер этих чанки можно задать, установив для параметра *chunksize* положительное целое число.
Обратите внимание, что это может привести к интенсивному использованию памяти для очень длинных итераблей. Рассмотрите возможность использования [`imap()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.imap "multiprocessing.pool.Pool.imap") или [`imap_unordered()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.imap_unordered "multiprocessing.pool.Pool.imap_unordered") с явным параметром *chunksize* для повышения эффективности.
`map_async`(*func*, *iterable*\[, *chunksize*\[, *callback*\[, *error\_callback*\]\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.map_async "Ссылка на это определение")
Вариант метода [`map()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.map "multiprocessing.pool.Pool.map"), который возвращает объект [`AsyncResult`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.AsyncResult "multiprocessing.pool.AsyncResult").
Если задан параметр *callback*, то он должен быть вызываемым и принимать один аргумент. То, когда результат становится готовым *callback*, применено к нему, это - то, если неудавшееся требование, в этом случае *error\_callback* не применен вместо этого.
Если задан параметр *error\_callback*, то он должен быть вызываемым и принимать один аргумент. Если целевая функция терпит неудачу, то *error\_callback* называют за исключением сущность.
Обратные вызовы должны быть завершены немедленно, поскольку в противном случае поток, обрабатывающая результаты, будет заблокирована.
`imap`(*func*, *iterable*\[, *chunksize*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.imap "Ссылка на это определение")
Более ленивый вариант [`map()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.map "multiprocessing.pool.Pool.map").
Аргумент *chunksize* совпадает с аргументом используемый методом [`map()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.map "multiprocessing.pool.Pool.map"). Очень долго iterables использование большого значение для *chunksize* может заставить работу закончить **гораздо** быстрее, чем использование дефолта значение `1`.
Также если *chunksize* является `1`, то метод `next()` итератора возвращенный методом [`imap()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.imap "multiprocessing.pool.Pool.imap") имеет необязательный параметр *timeout*: `next(timeout)` поднимет [`multiprocessing.TimeoutError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.TimeoutError "multiprocessing.TimeoutError"), если результат не может быть возвращенный в течение *timeout* секунд.
`imap_unordered`(*func*, *iterable*\[, *chunksize*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.imap_unordered "Ссылка на это определение")
То же как [`imap()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.imap "multiprocessing.pool.Pool.imap") за исключением того, что заказ результатов возвращенный iterator нужно считать произвольным. (Только при наличии только одного рабочего процесса порядок гарантирован как «правильный».
`starmap`(*func*, *iterable*\[, *chunksize*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.starmap "Ссылка на это определение")
Как [`map()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/functions.html#map "map") за исключением того, что элементы *iterable*, как ожидают, будут iterables, которые распакованы как аргументы.
Следовательно *iterable* `[(1,2), (3, 4)]` приводит к `[func(1,2), func(3,4)]`.
Добавлено в версии 3.3.
`starmap_async`(*func*, *iterable*\[, *chunksize*\[, *callback*\[, *error\_callback*\]\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.starmap_async "Ссылка на это определение")
Комбинация [`starmap()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.starmap "multiprocessing.pool.Pool.starmap") и [`map_async()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.map_async "multiprocessing.pool.Pool.map_async"), которая итерирует по *iterable* итераблей и вызывает *func* с итераблями распакованными. Возвращает объект результата.
Добавлено в версии 3.3.
`close`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.close "Ссылка на это определение")
Запрещает отправку дополнительных задач в пул. После завершения всех задач рабочие процессы завершаются.
`terminate`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.terminate "Ссылка на это определение")
Немедленная остановка рабочих процессов без завершения незавершенной работы. То, когда объект бассейна - мусор, собралось, [`terminate()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.terminate "multiprocessing.pool.Pool.terminate") немедленно назовут.
`join`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.join "Ссылка на это определение")
Дождитесь завершения рабочих процессов. Перед использованием [`close()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.close "multiprocessing.pool.Pool.close") необходимо вызвать [`terminate()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.terminate "multiprocessing.pool.Pool.terminate") или [`join()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.join "multiprocessing.pool.Pool.join").
Добавлено в версии 3.3: Объекты пула теперь поддерживают протокол управления контекст - см. раздел [Типы менеджера контекста](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#typecontextmanager). [`__enter__()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#contextmanager.__enter__ "contextmanager.__enter__") возвращает объект пула, [`__exit__()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#contextmanager.__exit__ "contextmanager.__exit__") вызывает [`terminate()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.terminate "multiprocessing.pool.Pool.terminate").
*class* `multiprocessing.pool.``AsyncResult`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.AsyncResult "Ссылка на это определение")
Класс результата возвращенный по [`Pool.apply_async()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.apply_async "multiprocessing.pool.Pool.apply_async") и [`Pool.map_async()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.map_async "multiprocessing.pool.Pool.map_async").
`get`(\[*timeout*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.AsyncResult.get "Ссылка на это определение")
Возвращает результат при его поступлении. Если *timeout* не является `None` и результат не поступает в течение *timeout* секунд, то [`multiprocessing.TimeoutError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.TimeoutError "multiprocessing.TimeoutError") поднимается. Если удаленное требование подняло исключение тогда, что исключение будет повторно поднято [`get()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.AsyncResult.get "multiprocessing.pool.AsyncResult.get").
`wait`(\[*timeout*\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.AsyncResult.wait "Ссылка на это определение")
Подождите, пока результат будет доступен, или до истечения *timeout* секунд.
`ready`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.AsyncResult.ready "Ссылка на это определение")
Возвращает, завершен ли вызов.
`successful`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.AsyncResult.successful "Ссылка на это определение")
Возвращает, выполнен ли вызов без возникновения исключения. Поднимет [`ValueError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#ValueError "ValueError"), если результат не готов.
Изменено в версии 3.7: Если результат не готов, [`ValueError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#ValueError "ValueError") поднимается вместо [`AssertionError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#AssertionError "AssertionError").
В следующем примере показано использование пула:
```
from multiprocessing import Pool
import time
def f(x):
return x*x
if __name__ == '__main__':
with Pool(processes=4) as pool: # запустить 4 процесса воркера
result = pool.apply_async(f, (10,)) # асинхронно вычислить "f(10)" в одном процессе
print(result.get(timeout=1)) # печатает "100", если только ваш компьютер не работает *очень* медленно
print(pool.map(f, range(10))) # печать "[0, 1, 4,..., 81]"
it = pool.imap(f, range(10))
print(next(it)) # печать "0"
print(next(it)) # печать "1"
print(it.next(timeout=1)) # печать "4" если ваш компьютер не *очень* медленный
result = pool.apply_async(time.sleep, (10,))
print(result.get(timeout=1)) # поднять multiprocessing.TimeoutError
```
### Слушатели и клиенты[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.connection "Ссылка на этот заголовок")
Обычно сообщение, проходящее между процессами, сделано, используя очереди, или при помощи [`Connection`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection "multiprocessing.connection.Connection") возражает возвращенный [`Pipe()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Pipe "multiprocessing.Pipe").
Однако модуль [`multiprocessing.connection`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.connection "multiprocessing.connection: API для работы с сокетами.") обеспечивает некоторую гибкость. Он в основном дает высокоуровневый ориентированный на сообщения API для работы с сокеты или Windows с именем пайпы. У этого также есть поддержка *digest authentication*, используя модуль [`hmac`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/hmac.html#module-hmac "hmac: Реализация ключевого хеширования для аутентификации сообщений (HMAC)"), и опроса многочисленных связей одновременно.
`multiprocessing.connection.``deliver_challenge`(*connection*, *authkey*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.deliver_challenge "Ссылка на это определение")
Отправка случайно сгенерированного сообщения на другой конец соединения и ожидание ответа.
Если ответ соответствует дайджесту сообщения с использованием клавиши *authkey*, то приветственное сообщение отправляется на другой конец соединения. В противном случае поднимается [`AuthenticationError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.AuthenticationError "multiprocessing.AuthenticationError").
`multiprocessing.connection.``answer_challenge`(*connection*, *authkey*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.answer_challenge "Ссылка на это определение")
Получение сообщения, вычисление дайджеста сообщения с использованием *authkey* в качестве ключа, а затем отправка дайджеста обратно.
Если приветственное сообщение не получено, возникает сообщение [`AuthenticationError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.AuthenticationError "multiprocessing.AuthenticationError").
`multiprocessing.connection.``Client`(*address*\[, *family*\[, *authkey*\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Client "Ссылка на это определение")
Попытка установить соединение с прослушивателем, который использует адрес *address*, возвращая [`Connection`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection "multiprocessing.connection.Connection").
Тип соединения определяется аргументом *family*, но обычно его можно опустить, поскольку его обычно можно вывести из формата *address*. (См. [Форматы адреса](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-address-formats))
Если *authkey* задан, а не None, он должен быть байтом строка и будет используемый в качестве секретного ключа для вызова аутентификации на основе HMAC. Аутентификация не выполняется, если *authkey* является None. [`AuthenticationError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.AuthenticationError "multiprocessing.AuthenticationError") возникает в случае сбоя аутентификации. См. [Ключи аутентификации](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-auth-keys).
*class* `multiprocessing.connection.``Listener`(\[*address*\[, *family*\[, *backlog*\[, *authkey*\]\]\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Listener "Ссылка на это определение")
Обертка для связанной сокет или Windows с именем пайп, которая «слушает» подключения.
*address* - адрес, который должен быть используемый связанным сокет или именованным пайп объекта прослушивателя.
Примечание
Если адрес „0.0.0.0“ будет используемый, то адрес не будет соединяемой конечной точкой на Windows. Если требуется соединяемая конечная точка, следует использовать „127.0.0.1“.
*family* - тип используемого сокет (или именованного пайп). Это может быть один из строки `'AF_INET'` (для TCP сокет), `'AF_UNIX'` (для домена Unix сокет) или `'AF_PIPE'` (для Windows с именем пайп). Из них только первый гарантированно доступен. Если *family* `None`, то семейство выводится из формата *address*. Если *address* также является `None`, то выбирается значение по умолчанию. Это семейство по умолчанию считается самым быстрым из доступных. См. [Форматы адреса](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-address-formats). Обратите внимание, что если *family* является `'AF_UNIX'` и адрес `None`, то сокет будет создан в частном временном каталоге, созданном с помощью [`tempfile.mkstemp()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/tempfile.html#tempfile.mkstemp "tempfile.mkstemp").
Если объект прослушивателя использует сокет, то *backlog* (по умолчанию 1) передается методу [`listen()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/socket.html#socket.socket.listen "socket.socket.listen") сокет после его привязки.
Если *authkey* задан, а не None, он должен быть байтом строка и будет используемый в качестве секретного ключа для вызова аутентификации на основе HMAC. Аутентификация не выполняется, если *authkey* является None. [`AuthenticationError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.AuthenticationError "multiprocessing.AuthenticationError") возникает в случае сбоя аутентификации. См. [Ключи аутентификации](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-auth-keys).
`accept`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Listener.accept "Ссылка на это определение")
Принять подключение на связанном сокете или именованный пайп объекта слушателя и возвращает объект [`Connection`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection "multiprocessing.connection.Connection"). Если идентификация предпринята и терпит неудачу, то поднимается [`AuthenticationError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.AuthenticationError "multiprocessing.AuthenticationError").
`close`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Listener.close "Ссылка на это определение")
Закрыть связанный сокет или именованный пайп объекта слушателя. Это вызывается автоматически при сборе мусора прослушивателя. Однако желательно называть его явно.
Объекты прослушивателя имеют следующие свойства только для чтения:
`address`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Listener.address "Ссылка на это определение")
Адрес, используемый объектом Listener.
`last_accepted`[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Listener.last_accepted "Ссылка на это определение")
Адрес, с которого пришло последнее принятое соединение. Если это недоступно, то это `None`.
Добавлено в версии 3.3: Объекты прослушивателя теперь поддерживают протокол управления контекст - см. раздел [Типы менеджера контекста](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#typecontextmanager). [`__enter__()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#contextmanager.__enter__ "contextmanager.__enter__") возвращает объект прослушивателя, а [`__exit__()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/stdtypes.html#contextmanager.__exit__ "contextmanager.__exit__") вызывает [`close()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Listener.close "multiprocessing.connection.Listener.close").
`multiprocessing.connection.``wait`(*object\_list*, *timeout=None*)[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.wait "Ссылка на это определение")
Подождите, пока объект в *object\_list* будет готов. Возвращает список тех объектов в *object\_list*, которые готовы. Если *timeout* является float, то вызов блокируется максимум на столько секунд. Если *timeout* будет `None` тогда, то он заблокирует в течение неограниченного периода. Отрицательное время ожидания эквивалентно нулевому времени ожидания.
Как для Unix, так и для Windows объект может отображаться в *object\_list*, если это так
- читаемый объект [`Connection`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection "multiprocessing.connection.Connection");
- подключенный и читаемый объект [`socket.socket`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/socket.html#socket.socket "socket.socket"); или
- [`sentinel`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.sentinel "multiprocessing.Process.sentinel") атрибут объекта [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process").
Соединение или объект сокет готов, когда имеются данные, доступные для чтения из него, или другой конец закрыт.
**Unix**: `wait(object_list, timeout)` почти эквивалентный `select.select(object_list, [], [], timeout)`. Разница в том, что, если [`select.select()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/select.html#select.select "select.select") прерывается сигналом, он может поднять [`OSError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#OSError "OSError") с числом ошибок `EINTR`, тогда как [`wait()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.wait "multiprocessing.connection.wait") не будет.
**Windows**: Элемент в *object\_list* должен или быть целочисленным обработчиком, который ожидает (waitable) (согласно определению используемый документацией функции Win32 `WaitForMultipleObjects()`), или это может быть объект с методом `fileno()`, с каким возвращает ручка сокет или пайп обращаются. (Обратите внимание, что дескрипторы пайпа и сокет **не** являются дескрипторами ожидания.
Добавлено в версии 3.3.
**Примеры**
Следующий код сервера создает слушателя, который использует `'secret password'` в качестве ключа идентификации. Затем он ожидает подключения и передает некоторые данные клиенту:
```
from multiprocessing.connection import Listener
from array import array
address = ('localhost', 6000) # семейство выведено как 'AF_INET'
with Listener(address, authkey=b'secret password') as listener:
with listener.accept() as conn:
print('connection accepted from', listener.last_accepted)
conn.send([2.25, None, 'junk', float])
conn.send_bytes(b'hello')
conn.send_bytes(array('i', [42, 1729]))
```
Следующая код подключается к серверу и получает некоторые данные от сервера:
```
from multiprocessing.connection import Client
from array import array
address = ('localhost', 6000)
with Client(address, authkey=b'secret password') as conn:
print(conn.recv()) # => [2.25, None, 'junk', float]
print(conn.recv_bytes()) # => 'hello'
arr = array('i', [0, 0, 0, 0, 0])
print(conn.recv_bytes_into(arr)) # => 8
print(arr) # => array('i', [42, 1729, 0, 0, 0])
```
Следующая код использует [`wait()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.wait "multiprocessing.connection.wait") для ожидания сообщений от нескольких процессов одновременно:
```
import time, random
from multiprocessing import Process, Pipe, current_process
from multiprocessing.connection import wait
def foo(w):
for i in range(10):
w.send((i, current_process().name))
w.close()
if __name__ == '__main__':
readers = []
for i in range(4):
r, w = Pipe(duplex=False)
readers.append(r)
p = Process(target=foo, args=(w,))
p.start()
# Мы закрываем записываемый конец пайп, чтобы убедиться, что p является
# единственным процессом, который владеет дескриптором для него. Это гарантирует,
# что когда p закроет свой дескриптор для записываемого конца, wait()
# быстро сообщит о читаемом конце как о прочитанном.
w.close()
while readers:
for r in wait(readers):
try:
msg = r.recv()
except EOFError:
readers.remove(r)
else:
print(msg)
```
#### Форматы адреса[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-address-formats "Ссылка на этот заголовок")
- Адрес `'AF_INET'` - кортеж формы `(hostname, port)`, где *hostname* - строка, а *port* - целое число.
- Адрес `'AF_UNIX'` - это строка, представляющий имя файла в файловой системе.
- Адрес `'AF_PIPE'` представляет собой строку вида `r'\\.\pipe{PipeName}'`. Чтобы использовать [`Client()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Client "multiprocessing.connection.Client") для подключения к именованному каналу на удаленном компьютере с именем *ServerName*, вместо этого следует использовать адрес формы `r'\ServerName\pipe{PipeName}'`.
Обратите внимание, что любая строка, начинающаяся с двух обратных косых черт, по умолчанию принимается как `'AF_PIPE'` адрес, а не `'AF_UNIX'` адрес.
### Ключи аутентификации[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-auth-keys "Ссылка на этот заголовок")
Когда каждый использует [`Connection.recv`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Connection.recv "multiprocessing.connection.Connection.recv"), полученными данными является автоматически unpickled. К сожалению, отмена извлечения данных из ненадежного источника является угрозой безопасности. Поэтому [`Listener`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Listener "multiprocessing.connection.Listener") и [`Client()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.connection.Client "multiprocessing.connection.Client") используйте модуль [`hmac`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/hmac.html#module-hmac "hmac: Реализация ключевого хеширования для аутентификации сообщений (HMAC)") для обеспечения дайджест-аутентификации.
Ключ аутентификации - это байт строка, который можно рассматривать как пароль: после установления соединения оба конца потребуют подтверждения того, что другой знает ключ аутентификации. (Демонстрирующий то, что оба конца используют тот же ключ, делает **не**, включают отправку ключа по связи.)
Если идентификацию запрошенный, но никакой ключ идентификации не определен тогда, возвращает значение `current_process().authkey` - используемый (см. [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process")). Этот значение будет автоматически унаследован любым объектом [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process"), что текущий процесс создает. Это означает, что (по умолчанию) все процессы многопроцессорной программы будут совместно использовать один ключ аутентификации, который может быть используемый при установке соединений между собой.
Подходящие ключи аутентификации также могут быть сгенерированы с использованием [`os.urandom()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/os.html#os.urandom "os.urandom").
### Логирование[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id22 "Ссылка на этот заголовок")
Доступна некоторая поддержка логирование. Однако следует отметить, что пакет [`logging`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/logging.html#module-logging "logging: Гибкая система регистрации событий для приложений.") не использует общие блокировки процессов, что позволяет (в зависимости от типа обработчик) смешивать сообщения из различных процессов.
`multiprocessing.``get_logger`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.get_logger "Ссылка на это определение")
Возвращает логгер используемый по [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм."). При необходимости будет создан новый.
При первом создании логгер имеет уровень `logging.NOTSET` и не имеет обработчик по умолчанию. Сообщения, отправляемые этому логгер, по умолчанию не распространяются на корневой логгер.
Обратите внимание, что в Windows дочерние процессы наследуют только уровень логгер родительского процесса - любая другая настройка логгер не наследуется.
`multiprocessing.``log_to_stderr`()[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.log_to_stderr "Ссылка на это определение")
Эта функция выполняет вызов [`get_logger()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.get_logger "multiprocessing.get_logger"), но в дополнение к возвращению логгер, созданного get\_logger, она добавляет обработчик, который отправляет вывод в [`sys.stderr`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/sys.html#sys.stderr "sys.stderr"), используя формат `'[%(levelname)s/%(processName)s] %(message)s'`.
Ниже приведен пример сеанса с включенной функцией логирование:
\>\>\>
```
>>> import multiprocessing, logging
>>> logger = multiprocessing.log_to_stderr()
>>> logger.setLevel(logging.INFO)
>>> logger.warning('doomed')
[WARNING/MainProcess] doomed
>>> m = multiprocessing.Manager()
[INFO/SyncManager-...] child process calling self.run()
[INFO/SyncManager-...] created temp directory /.../pymp-...
[INFO/SyncManager-...] manager serving at '/.../listener-...'
>>> del m
[INFO/MainProcess] sending shutdown message to manager
[INFO/SyncManager-...] manager exiting with exitcode 0
```
Полную таблицу уровней логирование см. в модуле [`logging`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/logging.html#module-logging "logging: Гибкая система регистрации событий для приложений.").
### Модуль [`multiprocessing.dummy`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.dummy "multiprocessing.dummy: Обертка заглушка вокруг потоков.")[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.dummy "Ссылка на этот заголовок")
[`multiprocessing.dummy`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.dummy "multiprocessing.dummy: Обертка заглушка вокруг потоков.") копирует API [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм."), но является не более чем оболочкой для модуля [`threading`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html#module-threading "threading: Потоковый параллелизм.").
В частности, функция `Pool`, предоставляемая [`multiprocessing.dummy`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.dummy "multiprocessing.dummy: Обертка заглушка вокруг потоков."), возвращает экземпляр [`ThreadPool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.ThreadPool "multiprocessing.pool.ThreadPool"), который является подклассом [`Pool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "multiprocessing.pool.Pool"), который поддерживает все те же вызовы методов, но использует пул рабочих потоков, а не рабочих процессов.
*class* `multiprocessing.pool.``ThreadPool`(\[*processes*\[, *initializer*\[, *initargs*\]\]\])[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.ThreadPool "Ссылка на это определение")
Объект пула потоков, который управляет пулом рабочих потоков, которым могут быть отправлены задания. Экземпляры [`ThreadPool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.ThreadPool "multiprocessing.pool.ThreadPool") полностью совместимы по интерфейсу с экземплярами [`Pool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "multiprocessing.pool.Pool"), и их ресурсами также необходимо правильно управлять, используя пул в качестве диспетчера контекста или вызывая [`close()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.close "multiprocessing.pool.Pool.close") и [`terminate()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool.terminate "multiprocessing.pool.Pool.terminate") вручную.
*processes* - количество используемых рабочих потоков. Если *processes* - `None`, то используется номер, возвращенный [`os.cpu_count()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/os.html#os.cpu_count "os.cpu_count").
Если *initializer* не `None`, то каждый рабочий процесс при запуске будет вызывать `initializer(*initargs)`.
В отличие от [`Pool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "multiprocessing.pool.Pool"), *maxtasksperchild* и *context* не могут быть предоставлены.
> Примечание
>
> [`ThreadPool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.ThreadPool "multiprocessing.pool.ThreadPool") имеет тот же интерфейс, что и [`Pool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "multiprocessing.pool.Pool"), который разработан на основе пула процессов и предшествует введению модуля [`concurrent.futures`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/concurrent.futures.html#module-concurrent.futures "concurrent.futures: Конурентное выполнение вычислений с использованием потоков или процессов."). Таким образом, он наследует некоторые операции, которые не имеют смысла для пула, поддерживаемого потоками, и имеет свой собственный тип для представления состояния асинхронных заданий, [`AsyncResult`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.AsyncResult "multiprocessing.pool.AsyncResult"), который не понимается никакими другими библиотеками.
>
> Пользователям обычно следует использовать [`concurrent.futures.ThreadPoolExecutor`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor "concurrent.futures.ThreadPoolExecutor"), который имеет более простой интерфейс, изначально спроектированный для потоков, и который возвращает экземпляры [`concurrent.futures.Future`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/concurrent.futures.html#concurrent.futures.Future "concurrent.futures.Future"), совместимые со многими другими библиотеками, включая [`asyncio`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/asyncio.html#module-asyncio "asyncio: Асинхронный I/O.").
## Программирование рекомендаций[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-programming "Ссылка на этот заголовок")
Существуют определенные руководящие принципы и идиомы, которых следует придерживаться при использовании [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.").
### Все методы начала[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id24 "Ссылка на этот заголовок")
Следующее относится ко всем методам запуска.
Избегайте разделенного состояние
> Насколько это возможно, следует стараться избегать переноса больших объемов данных между процессами.
>
> Вероятно, лучше всего использовать очереди или пайпы для обмена данными между процессами, чем использовать примитивы синхронизации более низкого уровня.
Picklability
> Убедитесь в том, что аргументы для методов прокси-серверов доступны.
Безопасность потоков прокси
> Не используйте прокси-объект из нескольких поток, если вы не защитите его с помощью блокировки.
>
> (Никогда нет проблемы с различными процессами, используя прокси *same*.)
Присоединение к процессам зомби
> В Unix, когда процесс заканчивается, но не был присоединен, он становится зомби. Никогда не должно быть очень многих, потому что каждый раз новый процесс начинается (или [`active_children()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.active_children "multiprocessing.active_children") называют), все законченные процессы, к которым еще не присоединились, будет присоединен. Кроме того, вызов [`Process.is_alive`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.is_alive "multiprocessing.Process.is_alive") завершенного процесса присоединится к процессу. Тем не менее, это, вероятно, хорошая практика, чтобы явно присоединиться ко всем процессам, которые вы начинаете.
Лучше наследовать, чем pickle/unpickle
> При использовании методов запуска *spawn* или *forkserver* многие типы из [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") должны быть подбираемыми, чтобы их могли использовать дочерние процессы. Однако обычно следует избегать отправки общих объектов другим процессам с использованием пайпов или очередей. Вместо этого следует упорядочить программу так, чтобы процесс, которому необходим доступ к общему ресурсу, созданному в другом месте, мог наследовать его от предшествующего процесса.
Постарайтесь не заканчивать процессы
> Используя метод [`Process.terminate`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.terminate "multiprocessing.Process.terminate"), чтобы остановить процесс склонно заставить любые общие ресурсы (такие как замки, семафоры, пайпы и очереди) в настоящее время являющийся используемый процессом становиться сломанными или недоступными к другим процессам.
>
> Поэтому, вероятно, лучше только рассмотреть использование [`Process.terminate`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.terminate "multiprocessing.Process.terminate") на процессах, которые никогда не используют общих ресурсов.
Объединение процессов, использующих очереди
> Следует иметь в виду, что процесс, поставивший элементы в очередь, будет ждать завершения до тех пор, пока все буферизированные элементы не будут поданы «питателем» поток в нижележащий пайп. (Дочерний процесс может вызвать метод [`Queue.cancel_join_thread`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Queue.cancel_join_thread "multiprocessing.Queue.cancel_join_thread") очереди, чтобы избежать такого поведения.
>
> Это означает, что при каждом использовании очереди необходимо убедиться, что все элементы, помещенные в очередь, будут удалены до присоединения процесса. В противном случае вы не можете быть уверены, что процессы, поставившие элементы в очередь, завершатся. Также следует помнить, что недемонические процессы будут присоединяться автоматически.
>
> Примером взаимоблокировки является следующее:
> ```
> from multiprocessing import Process, Queue
def f(q):
q.put('X' * 1000000)
if __name__ == '__main__':
queue = Queue()
p = Process(target=f, args=(queue,))
p.start()
p.join() # это мертвая блокировка
obj = queue.get()
> ```
> Фиксация здесь должна была бы обменять последние две линии (или просто удалить линию `p.join()`).
Явная передача ресурсов дочерним процессам
> На Unix, используя метод начала *fork*, дочерний процесс может использовать общий ресурс, созданный в родительском процессе, используя глобальный ресурс. Однако лучше передать объект в качестве аргумента конструктору для дочернего процесса.
>
> Кроме обеспечения совместимости код (потенциально) с Windows и другими методами запуска, это также гарантирует, что до тех пор, пока дочерний процесс еще жив, объект не будет мусором собран в родительском процессе. Это может быть важно, если какой-либо ресурс освобождается при сборе мусора объекта в родительском процессе.
>
> Таким образом для сущность:
> ```
> from multiprocessing import Process, Lock
def f():
... сделать что-то используя "lock" ...
if __name__ == '__main__':
lock = Lock()
for i in range(10):
Process(target=f).start()
> ```
> следует переписать как:
> ```
> from multiprocessing import Process, Lock
def f(l):
... сделать что-нибудь, используя "l" ...
if __name__ == '__main__':
lock = Lock()
for i in range(10):
Process(target=f, args=(lock,)).start()
> ```
Остерегайтесь замены [`sys.stdin`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/sys.html#sys.stdin "sys.stdin") на «файл, как объект»
> [`multiprocessing`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing "multiprocessing: Процессный параллелизм.") изначально безоговорочно вызвается:
> ```
> os.close(sys.stdin.fileno())
> ```
> в методе `multiprocessing.Process._bootstrap()` — это привело к проблемам с процессами в процессах. Это было изменено на:
> ```
> sys.stdin.close()
sys.stdin = open(os.open(os.devnull, os.O_RDONLY), closefd=False)
> ```
> Который решает основную проблему процессов, сталкивающихся друг с другом приводящим к плохой ошибке файла дескриптор, но вводит потенциальную опасность для заявлений, которые заменяют [`sys.stdin()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/sys.html#sys.stdin "sys.stdin") «подобным файлу объектом» с буферизующей продукцией. Эта опасность заключается в том, что если несколько процессов вызывают [`close()`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/io.html#io.IOBase.close "io.IOBase.close") на этом файловом объекте, это может привести к тому, что одни и те же данные будут очищены на объекте несколько раз, что приведет к повреждению.
>
> Если вы пишете подобный файлу объект и осуществляете ваш собственный кэширование, вы можете сделать его безопасным от вилки, храня pid каждый раз, когда вы прилагаете к кэш и отказу от кэш, когда pid изменяется. Например:
> ```
> @property
def cache(self):
pid = os.getpid()
if pid != self._pid:
self._pid = pid
self._cache = []
return self._cache
> ```
> Дополнительные сведения см. в разделах [bpo-5155](https://bugs.python.org/issue5155), [bpo-5313](https://bugs.python.org/issue5313) и [bpo-5331](https://bugs.python.org/issue5331)
### Методы запуска *spawn* и *forkserver*[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#spawn-forkserver "Ссылка на этот заголовок")
Есть некоторые дополнительное ограничение, которые не относятся к методу начала *fork*.
Больше picklability
> Убедитесь, что все аргументы для `Process.__init__()` доступны. Кроме того, если вы, подкласс [`Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process "multiprocessing.Process") тогда удостоверяется, что сущности будет picklable, когда метод [`Process.start`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.start "multiprocessing.Process.start") назовут.
Глобальные переменные
> Принять во внимание, что, если пробег код в дочернем процессе пытается получить доступ к глобальной переменной, то значение он видит (если таковые имеются) может не совпасть с значение в родительском процессе в то время, когда вызван [`Process.start`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.Process.start "multiprocessing.Process.start").
>
> Однако глобальные переменные, являющиеся только константами уровня модуля, не вызывают проблем.
Безопасный импорт основного модуля
> Удостоверьтесь, что главный модуль может быть безопасно импортирован новым Python интерпретатор, не вызывая непреднамеренные побочные эффекты (такой старт нового процесса).
>
> Например, использование метода начала *spawn* или *forkserver*, управляющего следующим модулем, потерпело бы неудачу с [`RuntimeError`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/exceptions.html#RuntimeError "RuntimeError"):
> ```
> from multiprocessing import Process
def foo():
print('hello')
p = Process(target=foo)
p.start()
> ```
> Вместо этого следует защитить «точку входа» программы, используя `if __name__ == '__main__':` следующим образом:
> ```
> from multiprocessing import Process, freeze_support, set_start_method
def foo():
print('hello')
if __name__ == '__main__':
freeze_support()
set_start_method('spawn')
p = Process(target=foo)
p.start()
> ```
> (Строка `freeze_support()` может быть опущена, если программа будет запущена нормально, а не заморожена.
>
> Это позволяет недавно порожденному Python интерпретатор безопасно импортировать модуль и затем управлять функцией `foo()` модуля.
>
> Аналогичные ограничения применяются в случае создания пула или менеджера в главном модуле.
## Примеры[¶](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-examples "Ссылка на этот заголовок")
Демонстрация создания и использования настраиваемых менеджеров и прокси:
```
from multiprocessing import freeze_support
from multiprocessing.managers import BaseManager, BaseProxy
import operator
##
class Foo:
def f(self):
print('you called Foo.f()')
def g(self):
print('you called Foo.g()')
def _h(self):
print('you called Foo._h()')
# A simple generator function
def baz():
for i in range(10):
yield i*i
# Proxy type for generator objects
class GeneratorProxy(BaseProxy):
_exposed_ = ['__next__']
def __iter__(self):
return self
def __next__(self):
return self._callmethod('__next__')
# Function to return the operator module
def get_operator_module():
return operator
##
class MyManager(BaseManager):
pass
# register the Foo class; make `f()` and `g()` accessible via proxy
MyManager.register('Foo1', Foo)
# register the Foo class; make `g()` and `_h()` accessible via proxy
MyManager.register('Foo2', Foo, exposed=('g', '_h'))
# register the generator function baz; use `GeneratorProxy` to make proxies
MyManager.register('baz', baz, proxytype=GeneratorProxy)
# register get_operator_module(); make public functions accessible via proxy
MyManager.register('operator', get_operator_module)
##
def test():
manager = MyManager()
manager.start()
print('-' * 20)
f1 = manager.Foo1()
f1.f()
f1.g()
assert not hasattr(f1, '_h')
assert sorted(f1._exposed_) == sorted(['f', 'g'])
print('-' * 20)
f2 = manager.Foo2()
f2.g()
f2._h()
assert not hasattr(f2, 'f')
assert sorted(f2._exposed_) == sorted(['g', '_h'])
print('-' * 20)
it = manager.baz()
for i in it:
print('<%d>' % i, end=' ')
print()
print('-' * 20)
op = manager.operator()
print('op.add(23, 45) =', op.add(23, 45))
print('op.pow(2, 94) =', op.pow(2, 94))
print('op._exposed_ =', op._exposed_)
##
if __name__ == '__main__':
freeze_support()
test()
```
Использование [`Pool`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing.pool.Pool "multiprocessing.pool.Pool"):
```
import multiprocessing
import time
import random
import sys
#
# Functions used by test code
#
def calculate(func, args):
result = func(*args)
return '%s says that %s%s = %s' % (
multiprocessing.current_process().name,
func.__name__, args, result
)
def calculatestar(args):
return calculate(*args)
def mul(a, b):
time.sleep(0.5 * random.random())
return a * b
def plus(a, b):
time.sleep(0.5 * random.random())
return a + b
def f(x):
return 1.0 / (x - 5.0)
def pow3(x):
return x ** 3
def noop(x):
pass
#
# Test code
#
def test():
PROCESSES = 4
print('Creating pool with %d processes\n' % PROCESSES)
with multiprocessing.Pool(PROCESSES) as pool:
#
# Tests
#
TASKS = [(mul, (i, 7)) for i in range(10)] + \
[(plus, (i, 8)) for i in range(10)]
results = [pool.apply_async(calculate, t) for t in TASKS]
imap_it = pool.imap(calculatestar, TASKS)
imap_unordered_it = pool.imap_unordered(calculatestar, TASKS)
print('Ordered results using pool.apply_async():')
for r in results:
print('\t', r.get())
print()
print('Ordered results using pool.imap():')
for x in imap_it:
print('\t', x)
print()
print('Unordered results using pool.imap_unordered():')
for x in imap_unordered_it:
print('\t', x)
print()
print('Ordered results using pool.map() --- will block till complete:')
for x in pool.map(calculatestar, TASKS):
print('\t', x)
print()
#
# Test error handling
#
print('Testing error handling:')
try:
print(pool.apply(f, (5,)))
except ZeroDivisionError:
print('\tGot ZeroDivisionError as expected from pool.apply()')
else:
raise AssertionError('expected ZeroDivisionError')
try:
print(pool.map(f, list(range(10))))
except ZeroDivisionError:
print('\tGot ZeroDivisionError as expected from pool.map()')
else:
raise AssertionError('expected ZeroDivisionError')
try:
print(list(pool.imap(f, list(range(10)))))
except ZeroDivisionError:
print('\tGot ZeroDivisionError as expected from list(pool.imap())')
else:
raise AssertionError('expected ZeroDivisionError')
it = pool.imap(f, list(range(10)))
for i in range(10):
try:
x = next(it)
except ZeroDivisionError:
if i == 5:
pass
except StopIteration:
break
else:
if i == 5:
raise AssertionError('expected ZeroDivisionError')
assert i == 9
print('\tGot ZeroDivisionError as expected from IMapIterator.next()')
print()
#
# Testing timeouts
#
print('Testing ApplyResult.get() with timeout:', end=' ')
res = pool.apply_async(calculate, TASKS[0])
while 1:
sys.stdout.flush()
try:
sys.stdout.write('\n\t%s' % res.get(0.02))
break
except multiprocessing.TimeoutError:
sys.stdout.write('.')
print()
print()
print('Testing IMapIterator.next() with timeout:', end=' ')
it = pool.imap(calculatestar, TASKS)
while 1:
sys.stdout.flush()
try:
sys.stdout.write('\n\t%s' % it.next(0.02))
except StopIteration:
break
except multiprocessing.TimeoutError:
sys.stdout.write('.')
print()
print()
if __name__ == '__main__':
multiprocessing.freeze_support()
test()
```
Пример использования очередей для подачи задач в коллекцию рабочих процессов и сбора результатов:
### [Содержание](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/contents.html)
- [`multiprocessing` — Процессный параллелизм](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html)
- [Введение](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id1)
- [Класс `Process`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#process)
- [Контексты и методы запуска](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id2)
- [Обмен объектами между процессами](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id3)
- [Синхронизация между процессами](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id4)
- [Совместное использование состояние между процессами](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id5)
- [Использование пула воркеров](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id6)
- [Ссылка](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id7)
- [`Process` и исключения](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id8)
- [Пайпы и очереди](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id9)
- [Разное](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id10)
- [Объекты связи](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id11)
- [Примитивы синхронизации](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id12)
- [Разделенные объекты `ctypes`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#ctypes)
- [Модуль `multiprocessing.sharedctypes`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.sharedctypes)
- [Менеджеры](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-managers)
- [Настраиваемые менеджеры](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id14)
- [Использование удаленного менеджера](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id15)
- [Прокси объекты](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-proxy-objects)
- [Очистка](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id17)
- [Процессные пулы](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.pool)
- [Слушатели и клиенты](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.connection)
- [Форматы адреса](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-address-formats)
- [Ключи аутентификации](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-auth-keys)
- [Логирование](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id22)
- [Модуль `multiprocessing.dummy`](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#module-multiprocessing.dummy)
- [Программирование рекомендаций](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-programming)
- [Все методы начала](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#id24)
- [Методы запуска *spawn* и *forkserver*](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#spawn-forkserver)
- [Примеры](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html#multiprocessing-examples)
#### Предыдущий раздел
[`threading` — Потоковый параллелизм](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html "предыдущая глава")
#### Следующий раздел
[`multiprocessing.shared_memory` — Предоставляет общую память для прямого доступа между процессами](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.shared_memory.html "следующая глава")
### Эта страница
- [Сообщить об ошибке](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/bugs.html)
«
### Навигация
- [указатель](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/genindex.html "Алфавитный указатель")
- [модули](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/py-modindex.html "Содержание модулей Python") \|
- [вперёд](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.shared_memory.html "multiprocessing.shared_memory — Предоставляет общую память для прямого доступа между процессами") \|
- [назад](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/threading.html "threading — Потоковый параллелизм") \|
- 
- [Python](https://digitology.tech/) »
- [3\.8.8 Документация](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/index.html) »
- [Стандартная библиотека Python](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/index.html) »
- [Конкурентное выполнение](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/library/concurrency.html) »
- \|
[Поддержать первод](http://grep.cs.msu.ru/python3.8_RU/digitology.tech/docs/python_3/donate.html)

©Авторские права Digitology.tech.
Обновлено: апр. 06, 2021. |
| Readable Markdown | null |
| Shard | 151 (laksa) |
| Root Hash | 13936146405119744351 |
| Unparsed URL | ru,msu!cs,grep,/python3.8_RU/digitology.tech/docs/python_3/library/multiprocessing.html h80 |