Python zeromq - несколько издателей для одного подписчика? - PullRequest
6 голосов
/ 15 июля 2011

Я хотел бы написать python скрипт (назовите его parent ), который выполняет следующее:

(1) определяет многомерный numpy массив

(2) forks 10 различных python сценариев (назовите их children ). Каждый из них должен иметь возможность read содержимое массива numpy из (1) в любой отдельный момент времени (пока они живы).

(3) каждый из сценариев child будет выполнять свою работу ( children НЕ делиться никакой информацией друг с другом)

(4) в любой момент времени сценарий parent должен иметь возможность принимать сообщения от всех своих потомков . Эти сообщения будут проанализированы родительским и приведут к изменению массива numpy из (1) .


Как мне поступить, работая в python в Linux среде? Я думал об использовании zeroMQ, и parent был бы единственным подписчиком , в то время как children все будут издателями ; это имеет смысл или есть лучший способ для этого?

Кроме того, как разрешить всем потомкам непрерывно читать содержимое массива numpy, который был определен parent ?

Ответы [ 3 ]

14 голосов
/ 22 мая 2012

Канал sub не обязательно должен быть привязанным, поэтому вы можете привязать подписчика, и каждый из дочерних каналов pub может подключиться к нему и отправить свои сообщения.В данном конкретном случае я думаю, что модуль multiprocessing лучше подходит, но я подумал, что в нем упоминается:

import zmq
import threading

# So that you can copy-and-paste this into an interactive session, I'm
# using threading, but obviously that's not what you'd use

# I'm the subscriber that multiple clients are writing to
def parent():
    context = zmq.Context()
    socket = context.socket(zmq.SUB)
    socket.setsockopt(zmq.SUBSCRIBE, 'Child:')
    # Even though I'm the subscriber, I'm allowed to get this party 
    # started with `bind`
    socket.bind('tcp://127.0.0.1:5000')

    # I expect 50 messages
    for i in range(50):
        print 'Parent received: %s' % socket.recv()

# I'm a child publisher
def child(number):
    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    # And even though I'm the publisher, I can do the connecting rather
    # than the binding
    socket.connect('tcp://127.0.0.1:5000')

    for data in range(5):
        socket.send('Child: %i %i' % (number, data))
    socket.close()

threads = [threading.Thread(target=parent)] + [threading.Thread(target=child, args=(i,)) for i in range(10)]
for thread in threads:
    thread.start()

for thread in threads:
    thread.join()

В частности, часть документации Core Messaging Patterns обсуждается тот факт, что для шаблонов любая сторона может связывать (а другая соединять).

4 голосов
/ 15 июля 2011

Я думаю, что имеет больше смысла использовать разъемы PUSH / PULL, поскольку у вас есть стандартный сценарий Вентилятор - Рабочие - Мойка , за исключением того, что Вентилятор и Мойка являются одним и тем же процессом.

Также рассмотрите возможность использования многопроцессорного модуля вместо ZeroMQ.Наверное, будет немного проще.

0 голосов
/ 26 июля 2011

В ZeroMQ может быть только один издатель на порт.Единственный (некрасивый) обходной путь - запускать каждый дочерний PUB-сокет на другом порту и заставлять родителя прослушивать все эти порты.

но шаблон конвейера, описанный в 0MQ, руководство пользователя - намного лучший способ сделать это.

...