python - python zerorpc多线程
问题描述
我正在尝试为 python 程序构建前端服务。我选择 zerorpc 在 NodeJS 和 python 之间进行通信,效果很好,唯一的问题是我不能正确地多线程 zerorpc。
我看过几篇关于 zerorpc 和普通线程如何相互不喜欢的帖子。但是,我的后端服务已经有些先进并使用了多个线程。
所以现在的问题是,是否有可能以某种方式将普通线程和 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()
预先感谢您帮助我!
解决方案
zerorpc 使用 gevent 实现并发(ioloop + coroutines 等)。Gevent 是单线程的,并且在初始化之后,只能从最初用于初始化它的线程中使用。在您的情况下,这是线程调用server.run()
. 因此,您只能与来自同一线程的 zerorpc 方法进行交互。
您可以使用猴子补丁(http://www.gevent.org/intro.html#monkey-patching),它可以有效地使您的Thread
对象表现得像协程。如果您仅将线程用于 IO 并发,那么这可能就足够了。
否则,如果您希望线程用于 CPU 并行性,一个行之有效的解决方案是将子进程工作者用作单独的线程。您可以在主服务器和工作人员之间使用 zerorpc(unix 套接字非常适合这里)。因为工作人员无论如何都是 CPU 绑定和本地的,所以您可以禁用服务器和工作人员之间的心跳 ( Client/Server(heartbeat=0)
)。
但是,我找不到有关如何安全地混合系统线程和 gevent 的任何详细信息。
推荐阅读
- java - 飞碟异常字体无法识别
- python - Sympy - 找到将距离最小化为三个圆周的点
- android - MPAndroidChart 中的 BarChart 不能为空
- python - 根据另一列填充熊猫列
- ios - Nativescript Angular ActivityIndicator spinner - 如何在 ios 中更改其大小?
- java - Swagger @ApiModelProperty 基于 HTTP 请求的灵活性
- c# - 为什么可变高度值是 0?
- sql - 如何使用 VQL 选择多个产品的 id?
- java - 如果句子包含撇号,Cucumber no match gherkin in French
- java - 使用列表在地图中分组时如何过滤年龄