我遇到了一些问题,我怀疑这是我的python程序无法正确处理的限制,我的程序无法在我点击Ctrl-C后立即调用BaseManager的注册类的方法,甚至是其他作为从多处理继承的类实现的进程。流程受到影响。我有一些方法想从Ctrl-C之后不能正确执行的进程中调用。
例如,以下代码无法在Ctrl-C之后调用TestClass的mt实例。
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
你有什么建议吗?我的代码中有什么变通方法或错误吗?
提前谢谢。
如果有人碰巧遇到这个问题,我会根据这个答案解决https://stackoverflow.com/a/21106459/1667319。这是的工作代码
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
干杯,
这是问题的重复,我在那里写道:
最简单的解决方案-使用启动管理器
manager.start(signal.signal, (signal.SIGINT, signal.SIG_IGN))
而不是manager.start()。并检查信号模块是否在您的导入中(导入信号)。
这个捕获并忽略管理器进程中的SIGINT(Ctrl-C)。