问题描述
我遇到了一些我怀疑是我的 python 程序无法正确处理的问题,我的程序无法在按下 Ctrl-C 后立即调用 BaseManager 注册类的方法,即使其他进程实现为从 multiprocessing.Process 继承的类会受到影响.我有一些我想从 Ctrl-C 后无法正确执行的进程调用的方法.
I am experiencing some issues that I suspect is a limitation of my python program to handle correctly, my program is not been able to call methods of a registered class of BaseManager immediately after I hit Ctrl-C, even other process implemented as classes that inherit from multiprocessing.Process are affected. I have some methods that I would like to call from process that don't execute correctly after Ctrl-C.
例如下面的代码在Ctrl-C之后不能调用TestClass的mt实例.
For example the following code is not able to call the mt instance of TestClass after Ctrl-C.
from multiprocessing.managers import BaseManager, NamespaceProxy import time class TestClass(object): def __init__(self, a): self.a = a def b(self): print self.a class MyManager(BaseManager): pass class TestProxy(NamespaceProxy): # We need to expose the same __dunder__ methods as NamespaceProxy, # in addition to the b method. _exposed_ = ('__getattribute__', '__setattr__', '__delattr__', 'b') def b(self): callmethod = object.__getattribute__(self, '_callmethod') return callmethod('b') MyManager.register('TestClass', TestClass, TestProxy) if __name__ == '__main__': manager = MyManager() manager.start() t = TestClass(1) print t.a mt = manager.TestClass(2) print mt.a mt.a = 5 mt.b() try: while 1: pass except (KeyboardInterrupt, SystemExit): time.sleep(0.1) mt.a = 7 mt.b() print "bye" pass Here is the console output 1 2 5 ^CTraceback (most recent call last): File "testManager.py", line 38, in <module> mt.a = 7 File "/usr/lib/python2.7/multiprocessing/managers.py", line 1028, in __setattr__ return callmethod('__setattr__', (key, value)) File "/usr/lib/python2.7/multiprocessing/managers.py", line 758, in _callmethod conn.send((self._id, methodname, args, kwds)) IOError: [Errno 32] Broken pipe
你有什么建议吗?我的代码中是否有任何解决方法或问题?
Do you have any suggestion? Is there any workaround or something wrong in my code?
提前致谢.
推荐答案
如果有人遇到这个问题,我根据这个答案解决了 https://stackoverflow.com/a/21106459/1667319.这是工作代码
If someone happen to had this issue, I solved based on this answer https://stackoverflow.com/a/21106459/1667319 . Here is the working code
from multiprocessing.managers import SyncManager, NamespaceProxy import time import signal #handle SIGINT from SyncManager object def mgr_sig_handler(signal, frame): print 'not closing the mgr' #initilizer for SyncManager def mgr_init(): signal.signal(signal.SIGINT, mgr_sig_handler) #signal.signal(signal.SIGINT, signal.SIG_IGN) # <- OR do this to just ignore the signal print 'initialized mananger' class TestClass(object): def __init__(self, a): self.a = a def b(self): print self.a class MyManager(SyncManager): pass class TestProxy(NamespaceProxy): # We need to expose the same __dunder__ methods as NamespaceProxy, # in addition to the b method. _exposed_ = ('__getattribute__', '__setattr__', '__delattr__', 'b') def b(self): callmethod = object.__getattribute__(self, '_callmethod') return callmethod('b') MyManager.register('TestClass', TestClass, TestProxy) if __name__ == '__main__': manager = MyManager() manager.start(mgr_init) t = TestClass(1) print t.a mt = manager.TestClass(2) print mt.a mt.a = 5 mt.b() try: while 1: pass except (KeyboardInterrupt, SystemExit): time.sleep(0.1) mt.a = 7 mt.b() print "bye" pass
干杯,