使用zeroRPC进行多处理的奇怪问题

时间:2014-11-29 04:16:47

标签: python multiprocessing rpc zeromq zerorpc

所以,我正在玩ZeroRPC和Tornado参与宠物项目,并且我使用ZeroRPC和python的多处理库遇到了一些问题。具体来说,我是以编程方式创建和运行新的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()

一切正常。我的理解是这两个实现应该是等价的,但不知何故它们不是。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

zerorpc使用gevent进行协作异步IO。您可能想要了解龙卷风,多处理和gevent是如何一起播放的。

我可以告诉你:

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

第1行和第2行正在创建并绑定当前进程的端口。但在第3和第4行,我能猜到的是:

  • fork被调用,进程中的所有线程都在fork中丢失
  • 任何zeromq socket&上下文现在已经死了(没有更多线程)。好消息是,可以销毁上下文,并创建一个新上下文(参见http://lists.zeromq.org/pipermail/zeromq-dev/2014-January/024536.html)。
  • 现在你的本地进程有一个端口,有一个活动的zeromq套接字,但是没有人从这个套接字读取(因此当你与它交谈时没有反应)。
  • 另一方面,在多进程的进程中,zerorpc正在运行,在原始zmq套接字的文件上调用recv。什么都不会来,zeromq已经死了。

没有测试,我只能猜测在新进程中完全运行zerorpc应该可以工作:

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

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

然后通过一些Manager对象或多进程提供的其他共享内存服务,您可以使新进程中的zerorpc服务器访问并与您的本地进程共享数据。

另一方面,如果你要做的是调用server.run()而不阻塞,如果你只使用gevent,我会告诉你只需在自己的协程中运行它:

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

也许你可以直接从龙卷风协程/ asyunc函数中调用server.run。也许有一种方法可以整合gevent和龙卷风(比如这个链接建议:https://bmmh.wordpress.com/2012/10/07/tornado-and-gevent/),我现在还不太了解你的帮助。