2015-08-22 2 views
1

У меня проблема:Многопроцессорность Python - функциональная связь между двумя процессами

У меня есть два разных класса; назовем их interface и worker. Интерфейс должен принимать запросы извне и мультиплексировать их нескольким работникам.

Вопреки почти каждый пример я нашел, у меня есть несколько особенностей:

  • Рабочие не должны быть воссоздана для каждого запроса.
  • Рабочие разные; на запрос workers[0] не может быть получен ответ workers[1]. Это мультиплексирование выполняется в interface.
  • У меня есть ряд функциональных вызовов, которые сложно моделировать через события или простые очереди.
  • Существует несколько разных запросов, которые затрудняли бы одну очередь на запрос.

Например, предположим, что каждый работник хранит одно целое число (допустим, количество вызовов, полученных этим рабочим). В не-параллельной обработки, я хотел бы использовать что-то вроде этого:

class interface(object): 
    workers = None #set somewhere else. 

    def get_worker_calls(self, worker_id): 
     return self.workers[worker_id].get_calls() 

class worker(object) 
    calls = 0 

    def get_calls(self): 
     self.calls += 1 
     return self.calls 

 

Это, очевидно, не работает. Что значит?

Или, возможно, более уместно, у меня нет опыта многопроцессорности. Есть ли парадигма дизайна, которую я пропускаю, что бы легко решить вышеизложенное?

Спасибо!

 

 

Для справки, я рассмотрел несколько подходов, и я не смог найти хороший:

  • Используйте один запрос и ответ очереди. Я отбросил эту идею, так как это либо блокирует interface 'для времени ответа текущего рабочего (что делает его плохо масштабируемым), либо потребует от меня отправки дополнительной информации.
  • Использование одной очереди запросов. Каждое сообщение содержит трубку для возврата ответа на этот запрос. После исправления issue with being unable to send pipes via pipes у меня возникли проблемы с закрытием трубы, если вы не отправляете оба конца по соединению.
  • Использование одной очереди запросов. Каждое сообщение содержит очередь для возврата ответа на этот запрос. Сбой, так как я не могу отправлять очереди через очереди, но трюк с изменением не работает.
  • Вышеупомянутое относится также к соответствующим объектам, созданным менеджером.

ответ

0

Многопроцессорное обслуживание означает, что у вас есть 2+ отдельных процесса. Невозможно напрямую обращаться к памяти из одного процесса в другой (как при многопоточности).

Ваш лучший снимок - использовать какой-то внешний механизм очереди, вы можете начать с Celery или RQ. RQ проще, но сельдерей имеет встроенный мониторинг.

Но вы должны знать, что Multiprocessing будет работать только в том случае, если Celery/RQ смогут «упаковать» необходимые функции/классы и отправить их другому процессу. Поэтому вам нужно использовать функции уровня __main__ (которые находятся в верхней части файла, не принадлежат ни одному классу).

Вы всегда можете реализовать его самостоятельно, Redis очень прост, ZeroMQ и RabbitMQ также хороши.

Beaver library - хороший пример того, как обращаться с многопроцессорной обработкой в ​​python с использованием очереди ZeroMQ.

Смежные вопросы