在atexit中引用其他模块
我有一个函数,负责在程序结束时杀掉一个子进程:
class MySingleton:
def __init__(self):
import atexit
atexit.register(self.stop)
def stop(self):
os.kill(self.sel_server_pid, signal.SIGTERM)
但是当这个函数被调用时,我收到了一个错误信息:
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'
看起来在调用 atexit
之前,os
和 signal
这两个模块被卸载了。重新导入它们可以解决这个问题,但我觉得这种情况有点奇怪——这些模块在我注册处理程序之前就已经导入了,为什么在我自己的退出处理程序运行之前它们又被卸载了呢?
1 个回答
9
在程序结束时,无法保证事物被销毁的顺序,所以最好让通过atexit
注册的函数是自给自足的。比如,在你的情况下:
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)
这样做比重新导入模块要好(重新导入模块可能会导致程序结束时变慢,甚至出现无尽的循环,虽然对于像os
这样的“系统提供”的模块,这种风险较小)。