2014-11-29 5 views
3

Итак, я играю с ZeroRPC и Tornado для проекта домашних животных, и у меня возникли проблемы с использованием ZeroRPC в сочетании с многопроцессорной библиотекой python. В частности, я создание и запуск новых серверов ZeroRPC программно, но, как правило, при запуске, сервер zerorpc блокирует, так что моя мысль была бросить его в другой процесс, как так:Странные проблемы с многопроцессорной обработкой с zeroRPC

server = zerorpc.Server(FuncWrapper()) 
server.bind(server_address) 
process = multiprocessing.Process(target=server.run) 
process.start() 

Однако, когда я делаю это , вызывающий сервер RPC просто зависает, что является типичным поведением, когда конечная точка не была правильно создана. Однако, если я просто позволю серверу запустить блок и вызовет его так:

serhouldver = zerorpc.Server(FuncWrapper()) 
server.bind(server_address) 
server.run() 

Все работает нормально. Мое понимание заключалось в том, что эти две реализации должны быть эквивалентными, но почему-то это не так.

Любые идеи?

ответ

0

zerorpc использует gevent для совместного асинхронного ввода-вывода. Вы можете посмотреть, как торнадо, многопроцессорность и gevent играют все вместе.

За то, что я могу сказать в:

server = zerorpc.Server(FuncWrapper()) 
server.bind(server_address) 
process = multiprocessing.Process(target=server.run) 
process.start() 

линия 1 и 2 являются создание и связывание порта на текущем процессе. Но в строке 3 и 4, что я могу догадаться, что происходит это:

  • вилка называется, все потоки в процессе теряются в вилке
  • любой ZeroMQ сокет & контекст мертв сейчас (не более нити) , Хорошая новость: контекст может быть уничтожен, а новый создан (см. http://lists.zeromq.org/pipermail/zeromq-dev/2014-January/024536.html).
  • Теперь у вас есть порт, открытый в вашем локальном процессе, с активным сокером zeromq, но никто не читает из этого сокета (следовательно, никакой реакции, когда вы с ним разговариваете).
  • С другой стороны, в процессе многопроцессорного процесса выполняется zerorpc, вызывая recv на реликвии исходного сокета zmq. Ничего никогда не придет, zeromq уже мертв.

Без тестирования, я могу только предположить, что работает zerorpc полностью в новом процессе должны работать:

def ZeroRPC_Service(): 
    server = zerorpc.Server(FuncWrapper()) 
    server.bind(server_address) 
    server.run() 

process = multiprocessing.Process(target=ZeroRPC_Service) 
process.start() 

Затем с помощью какого-либо объекта диспетчера или других служб общей памяти, предлагаемые многопроцессорных, вы могли бы сделать zerorpc сервер в новом процессе доступа и обмениваться данными с вашим локальным процессом.

На стороне записки, если то, что вы пытаетесь сделать, это server.run вызов() без блокировки, если вы использовали только GEvent, я бы сказал вам, чтобы просто запустить его в своей собственной сопрограмме:

server = zerorpc.Server(FuncWrapper()) 
server.bind(server_address) 
server_coro = gevent.spawn(server.run) 

Возможно, вы можете позвонить по телефону server.run с помощью функции tornado coroutine/asyunc. Возможно, есть способ интегрировать gevent и tornado (например, эта ссылка предлагает: https://bmmh.wordpress.com/2012/10/07/tornado-and-gevent/), я не знаю достаточно, чтобы помочь вам на этом этапе.