停止 Python Multiprocess BaseManager 'serve_forever' 服务器?



我在Python 3.6中进行了以下设置,用于进程间通信:

from multiprocessing.managers import BaseManager
class MyManager(BaseManager): pass
MyManager.register('get_instance', callable=lambda:my_instance)
m = MyManager(address=('', 50000), authkey=b'key')
s = m.get_server()
s.serve_forever()

为了避免阻塞较大应用程序的消息循环,我使用了一个线程来包含此设置。因此s.serve_forever()实际上在线程的run函数中运行。

这是根据文档完成的。并且设置本身在客户端管理器调用共享实例时工作正常。

但是,我发现没有办法停止这个"serve_forever"服务器。由于文档没有提到这一点,我检查了源代码。有一个stop_event据说我可以set退出循环。但它没有奏效,因为accepter守护程序/线程仍在运行。而且我无法在服务器对象上调用shutdown,因为我没有套接字对象c

那么如何关闭此服务器呢?

使用BaseManager.start()对我来说并不是一个真正的选择,因为在我的情况下,服务器共享一个异步消息循环,该循环只能由启动进程访问。BaseManager.start()会生成一个不再有权访问消息循环的新进程。 另一方面,get_server().serve_forever()在调用进程中运行。

在服务器中尝试此操作:

import threading
s = m.get_server()
stop_timer = threading.Timer(1, lambda:s.stop_event.set())
MyManager.register('stop', callable=lambda:stop_timer.start())
s.serve_forever()

在客户端中:

MyManager.register('stop')
m.stop()

更新:

我通过延迟stop_event.set()解决了超时问题threading.Timer

老:

但是,在机器上,由于stop()方法无法接收数据,您会遇到长时间的超时,这个答案谈到了这一点 - 但我无法让它工作:

正确断开多处理遥控器的连接

我是多处理管理器的新手,如果我找到更好的解决方案,我会更新这个答案。(更新:找到,更新(

这是读取multiprocessing.managers源后的黑客攻击,从_finalize_manager()中剥离,基本上是创建与服务器的连接并发送关机消息

from multiprocessing.managers import dispatch,listener_client
_Client = listener_client['pickle'][1]
# address and authkey same as when started the manager
conn = _Client(address=('127.0.0.1', 50000), authkey=b'key')
dispatch(conn, None, 'shutdown')
conn.close()

你可以包装/使用管理器启动/关闭来避免这个永远运行的服务器(start((为你启动一个服务器(:

m = MyManager(address=('', 50000), authkey=b'key')
m.start()
# do something
m.shutdown()

相关内容

  • 没有找到相关文章

最新更新