python zerorpc多线程

时间:2019-01-17 17:27:31

标签: python multithreading zerorpc

我正在尝试为python程序构建前端服务。我选择zerorpc在NodeJS和python之间进行通信,效果很好,我唯一遇到的问题是我无法正确地使用多线程zerorpc。
我看过几篇关于零rpc和普通线程如何彼此不喜欢的文章。但是我的后端服务已经有点先进,并且使用了多个线程。
因此,现在的问题是,是否可以以某种方式将普通线程和zerorpc结合起来,还是必须重写我的主代码以利用与zerorpc相同的线程库?
我在普通线程中遇到的主要问题是启动服务器的线程完全冻结,因此无法再关闭。 这是我当前启动服务器的方式:

self.communication_thread = Thread(target=communication_server.start_communication_server)
self.communication_thread.start()

def start_communication_server():
    global server
    addr = 'tcp://127.0.0.1:4242'
    server = zerorpc.Server(CommunicationServer())
    server.bind(addr)
    print('Created a new communicationserver running on {}'.format(addr))
    server.run()

我还尝试使用以下功能杀死服务器,但这会导致异常,这不是所希望的

def kill_server():
    global server
    server.stop()

已经提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

zerorpc与gevent(ioloop +协程等)实现并发。 Gevent是单线程的,初始化后只能从最初用于初始化它的线程中使用。就您而言,这是调用server.run()的线程。因此,您只能与同一线程中的zerorpc方法进行交互。

您可以使用猴子补丁(http://www.gevent.org/intro.html#monkey-patching)来有效地使Thread对象表现得像协程。如果仅将线程用于IO并发,那么这可能就足够了。

否则,如果您希望线程具有CPU并行性,那么一种行之有效的解决方案是将子进程工作程序用作单独的线程。您可以在主服务器和工作服务器之间使用zerorpc(unix套接字在这里非常合适)。由于工作线程始终受CPU约束并且是本地的,因此您可以禁用服务器和工作线程(Client/Server(heartbeat=0))之间的心跳。

但是我找不到有关如何安全地混合系统线程和gevent的任何详细信息。