На этом шаге мы рассмотрим использование модуля muhipmcessmg.connection.
Вы запускаете множество копий интерпретатора Python - возможно, на разных компьютерах, - и вы хотели бы обмениваться данными между интерпретаторами через сообщения.Вам нужен простой способ выполнить функции или методы в программах Python, работающих на удаленных компьютерах.
С помощью модуля muhipmcessmg.connection достаточно легко наладить общение между интерпретаторами. Вот простой пример эхо-сервера:
from multiprocessing.connection import Listener import traceback def echo_client(conn): try: while True: msg = conn.recv() conn.send(msg) except EOFError: print('Connection closed') def echo_server(address, authkey): serv = Listener(address, authkey=authkey) while True: try: client = serv.accept() echo_client(client) except Exception: traceback.print_exc() echo_server(('', 25000), authkey=b'peekaboo')
Вот простой пример соединения клиента с сервером и отправки сообщений:
>>> from multiprocessing.connection import Client >>> c = Client(('localhost', 25000), authkey=b'peekaboo') >>> c.send('hello') >>> c.recv() 'hello' >>> c.send(42) >>> c.recv() 42 >>> c.send([1, 2, 3, 4, 5]) >>> c.recv() [1, 2, 3, 4, 5] >>>
В отличие от низкоуровневого сокета, сообщения остаются неизменными (каждый объект, отосланный с использованием send(), получается целиком и
полностью с помощью recv()). Объекты сериализованы с помощью pickle. Так что любой совместимый с pickle объект может быть
отправлен или получен через это соединение.
Есть много пакетов и библиотек, которые связаны с той или иной формой передачи сообщений: ZeroMO, Celery и т. д. В качестве альтернативы вы можете склониться к написанию слоя сообщений над низкоуровневыми сокетами. Однако иногда вам нужно простое решение. Библиотека multiprocessing.connection именно такова: используя несколько простых примитивов, вы легко соедините интерпретаторы вместе и заставите их обмениваться сообщениями.
Если вы знаете, что интерпретаторы будут запускаться на одном и том же компьютере, то можете использовать альтернативную форму сетевых взаимодействий, такую как сокеты домена UNIX или именованные каналы Windows. Чтобы создать соединение через сокет домена UNIX, просто измените адрес на имя файла:
s = Listener('/tmp/myconn', authkey=b'peekaboo')
Чтобы создать соединение через именованный канал Windows, используйте имя файла таким образом:
s = Listener(r'\\.\pipe\myconn', authkey=b'peekaboo')
Общее правило: вы не должны использовать multiprocessing для реализации публичных сервисов. Параметр authkey, передаваемый Client() и Listener(), помогает аутентифицировать конечные точки соединения. Попытки соединения с неправильным ключом будут возбуждать исключение. Этот модуль лучше подходит для длительных соединений (но не для большого количества коротких соединений). Например, два интерпретатора могут установить соединение при запуске и поддерживать соединение активным на всем протяжении выполнения задачи.
Не используйте multiprocessing, если вам нужен более низкоуровневый контроль над аспектами соединения. Например, если вы хотите использовать тайм-ауты, неблокирующий ввод-вывод или что-то похожее, вам стоит применить другую библиотеку или реализовать эти возможности поверх сокетов.
На следующем шаге мы рассмотрим реализацию удаленного вызова процедур.