proceso - El BaseManager de multiprocesamiento python registró la pérdida de conexión de clase inmediatamente después de Ctrl-C
proceso en python (2)
Estoy experimentando algunos problemas que sospecho que es una limitación de mi programa python para manejarlos correctamente, mi programa no ha podido invocar métodos de una clase registrada de BaseManager inmediatamente después de presionar Ctrl-C, incluso otro proceso implementado como clases que heredan de multiprocesamiento. Los procesos se ven afectados. Tengo algunos métodos que me gustaría llamar desde un proceso que no se ejecuta correctamente después de Ctrl-C.
Por ejemplo, el siguiente código no puede llamar a la instancia mt de TestClass después de 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
¿Tienes alguna sugerencia? ¿Hay alguna solución o algo mal en mi código?
Gracias por adelantado.
Esto es una pregunta duplicada y escribí allí:
La solución más simple: iniciar el administrador con
manager.start(signal.signal, (signal.SIGINT, signal.SIG_IGN))
en lugar de manager.start (). Y compruebe si el módulo de señal está en sus importaciones (señal de importación).
Esta captura e ignora SIGINT (Ctrl-C) en el proceso del administrador.
Si alguien tiene este problema, lo resuelvo con esta respuesta https://.com/a/21106459/1667319 . Aquí está el código de trabajo
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
Aclamaciones,