停止Python多处理BaseManager' serve_forever'服务器?

时间:2017-07-06 05:03:27

标签: python python-3.x process multiprocessing python-multiprocessing

我在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函数内运行。

这是根据documentation完成的。设置本身在客户经理调用共享实例时工作正常。

然而,我发现没有办法阻止这个' serve_forever'服务器。由于文档没有提到这一点,我检查了source code。有一个stop_event据说我可以set退出循环。但由于accepter守护程序/线程仍在运行,因此无法正常工作。我无法在服务器对象上调用shutdown,因为我没有套接字对象c

那么如何关闭此服务器?

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

2 个答案:

答案 0 :(得分:1)

在服务器上尝试:

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来解决了超时问题

OLD:

但是,在机器之间,由于stop()方法无法接收数据,您会遇到长时间的超时,此答案是关于这一点的-但我无法使它起作用:

properly disconnect multiprocessing remote manager

我是多处理经理的新手,如果我找到更好的解决方案,我将更新此答案。 (更新:已找到,已更新)

答案 1 :(得分:0)

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

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