Hacer referencia a otros módulos en atexit
Pregunta
Tengo una función que es responsable de matar a un proceso hijo cuando termina el programa:
class MySingleton:
def __init__(self):
import atexit
atexit.register(self.stop)
def stop(self):
os.kill(self.sel_server_pid, signal.SIGTERM)
Sin embargo, me sale un mensaje de error cuando esta función se llama:
Traceback (most recent call last):
File "/usr/lib/python2.5/atexit.py", line 24, in _run_exitfuncs
func(*targs, **kargs)
File "/home/commando/Development/Diploma/streaminatr/stream/selenium_tests.py", line 66, in stop
os.kill(self.sel_server_pid, signal.SIGTERM)
AttributeError: 'NoneType' object has no attribute 'kill'
Parece que los módulos os
y signal
conseguir descargada antes atexit
se llama. Volver a importar los resuelve el problema, pero este comportamiento parece extraño para mí - estos módulos son importados antes de que yo registro mi manejador, ¿por qué se descargaban ante mis propias carreras de controlador de salida
Solución
No hay garantías firmes sobre el orden en que las cosas se destruyen en el tiempo de terminación del programa, por lo que es mejor para asegurar funciones atexit
registradas son independientes. Por ejemplo, en su caso:
class MySingleton:
def __init__(self):
import atexit
atexit.register(self.stop)
self._dokill = os.kill
self._thesig = signal.SIGTERM
def stop(self):
self._dokill(self.sel_server_pid, self._thesig)
Esto es preferible a los módulos de re-importación (que podría concebiblemente causa desaceleración de la terminación del programa e incluso interminables bucles, sin embargo, que el riesgo es menor para los módulos "proporcionados por el sistema", como os
).