我在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()
在调用过程中运行。
答案 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()