【问题标题】:How do I run zeroRpc server in thread in python?如何在 python 的线程中运行 zeroRpc 服务器?
【发布时间】:2016-11-27 12:41:42
【问题描述】:

我在 python 中启动 zeroRPC 服务器时遇到问题。我是按照official example 做的,但是当我调用run() 方法时,它在无限循环中工作,所以我的程序在启动此服务器后无法继续。我试图在新线程中运行它,但出现以下异常:

LoopExit: ('This operation would block forever', <Hub at 0x7f7a0c8f37d0 epoll pending=0 ref=0 fileno=19>)

我真的不知道如何解决它。有什么想法吗?

【问题讨论】:

  • 我想你误解了它的用途。当然它会阻塞,它正在等待接收消息。为什么您希望程序“继续”?
  • 因为这是一个更大的项目,与第二方的沟通只是其中的一部分。我还与 HW(arduino) 通信,它在自己的线程中工作,所有通信都应由主脚本控制。我不知道,也许这只是糟糕的应用程序设计,你认为我应该怎么做? @丹尼尔罗斯曼

标签: python multithreading server zeromq zerorpc


【解决方案1】:

简而言之,您不能将 os 线程与 zerorpc 一起使用。

更长的答案:zerorpc-python 使用 gevent 进行 IO。这意味着您的项目必须使用 gevent 并与之兼容。原生 OS 线程和 gevent 协程(也称为 greenlet、green 线程等)并不是真正的朋友。

gevent (http://www.gevent.org/gevent.threadpool.html) 中有一个本地线程池选项。

您不能生成本地操作系统线程并在其中运行 gevent 协程(包括 zerorpc)。

如果您所做的一切都使用 gevent 协程,那么不要在本机线程中运行 run(),而是在 gevent coroutine/greenlet/greenthread 中运行它,如下所示:

# starts the server in its own greenlet
gevent.spawn(myserver.run)
# zerorpc will spawn many more greenlet as needed.
# they all need to run cooperatively

# here we are continuing on the main greenlet.
# as a single greenlet can execute at a time, we must never block
# for too long. Using gevent IOs will cooperatively yield for example.
# Calling gevent.sleep() will yield as well.
while True:
  gevent.sleep(1)

注意:如果 gevent 不是一个选项,解决方案是实现一个不使用 gevent 并在 Python 之外实现其 IO 的 zerorpc-python 版本,但这有一个有趣的复杂性,而且不会很快发生.

【讨论】:

  • 这有点让 zerorpc 的用处非常有限。
  • 在实践中,cpython; python的参考实现;由于全局解释器锁,实际上并没有多线程。因此,您不会损失太多,并获得与异步 IO 的协作协同程序。此外,并发和并行代码很难编写。 gevent 降低了并发没有并行性的门槛。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 1970-01-01
  • 1970-01-01
  • 2019-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多