运行 关闭 Python 守护进程时的代码
Running code when closing a Python daemon
我正在使用著名的 code referenced here or here 在 Python 中做一个守护进程,像这样:
import sys, daemon
class test(daemon.Daemon):
def run(self):
self.db = somedb.connect() # connect to a DB
self.blah = 127
with open('blah0.txt', 'w') as f:
f.write(self.blah)
# doing lots of things here, modifying self.blah
def before_stop(self):
self.db.close() # properly close the DB (sync to disk, etc.)
with open('blah1.txt', 'w') as f:
f.write(self.blah)
daemon = test(pidfile='_.pid')
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.before_stop() # AttributeError: test instance has no attribute 'blah'
daemon.stop()
问题是当调用 ./myscript.py stop
并因此调用 daemon.before_stop()
时,不再有对 self.blah
的引用!
AttributeError: test instance has no attribute 'blah'
因此使用这种守护进程方法,在停止守护进程之前不可能访问守护进程的变量...
问题:如何访问守护程序 class' 之前的变量:
停止 ./myscript.py stop
被 SIGTERM 停止
(被杀?)
Daemon
class 调用before_stop()
时不会检索以前的对象,它只是通过PID 找到进程并用SIGTERM
杀死。如果您需要一些实例属性,请在 __init__()
中初始化它们,或者将它们写在某个临时文件中以便稍后在 before_stop()
实现中读取它们。
作为一般规则,您应该始终初始化 __init__()
内的所有实例绑定属性。
守护进程代码向守护进程发送 SIGTERM 信号,要求其停止。如果您希望某些东西 运行 由守护进程本身,它必须是来自信号处理程序或 atexit.register
调用方法的 运行。
daemonize
方法已经安装了这样的方法,只需从那里调用beforestop
:
# this one could be either in a subclass or in a modified base daemeon class
def delpid(self):
if hasattr(self, 'before_stop'):
self.before_stop()
os.remove(self.pidfile)
# this one should be in subclass
def before_stop(self):
self.db.close() # properly close the DB (sync to disk, etc.)
with open('blah1.txt', 'w') as f:
f.write(self.blah)
但这还不够! Python 标准库文档说 atexit
:
The functions registered via this module are not called when the program is killed by a signal not handled by Python
由于该进程需要接收 SIGTERM 信号,因此您必须安装一个处理程序。如其中一个active state recipe所示,它非常简单:如果程序收到信号就要求程序停止:
...
from signal import signal, SIGTERM
...
atexit.register(self.delpid)
signal(SIGTERM, lambda signum, stack_frame: exit(1))
我正在使用著名的 code referenced here or here 在 Python 中做一个守护进程,像这样:
import sys, daemon
class test(daemon.Daemon):
def run(self):
self.db = somedb.connect() # connect to a DB
self.blah = 127
with open('blah0.txt', 'w') as f:
f.write(self.blah)
# doing lots of things here, modifying self.blah
def before_stop(self):
self.db.close() # properly close the DB (sync to disk, etc.)
with open('blah1.txt', 'w') as f:
f.write(self.blah)
daemon = test(pidfile='_.pid')
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.before_stop() # AttributeError: test instance has no attribute 'blah'
daemon.stop()
问题是当调用 ./myscript.py stop
并因此调用 daemon.before_stop()
时,不再有对 self.blah
的引用!
AttributeError: test instance has no attribute 'blah'
因此使用这种守护进程方法,在停止守护进程之前不可能访问守护进程的变量...
问题:如何访问守护程序 class' 之前的变量:
停止
./myscript.py stop
被 SIGTERM 停止
(被杀?)
Daemon
class 调用before_stop()
时不会检索以前的对象,它只是通过PID 找到进程并用SIGTERM
杀死。如果您需要一些实例属性,请在 __init__()
中初始化它们,或者将它们写在某个临时文件中以便稍后在 before_stop()
实现中读取它们。
作为一般规则,您应该始终初始化 __init__()
内的所有实例绑定属性。
守护进程代码向守护进程发送 SIGTERM 信号,要求其停止。如果您希望某些东西 运行 由守护进程本身,它必须是来自信号处理程序或 atexit.register
调用方法的 运行。
daemonize
方法已经安装了这样的方法,只需从那里调用beforestop
:
# this one could be either in a subclass or in a modified base daemeon class
def delpid(self):
if hasattr(self, 'before_stop'):
self.before_stop()
os.remove(self.pidfile)
# this one should be in subclass
def before_stop(self):
self.db.close() # properly close the DB (sync to disk, etc.)
with open('blah1.txt', 'w') as f:
f.write(self.blah)
但这还不够! Python 标准库文档说 atexit
:
The functions registered via this module are not called when the program is killed by a signal not handled by Python
由于该进程需要接收 SIGTERM 信号,因此您必须安装一个处理程序。如其中一个active state recipe所示,它非常简单:如果程序收到信号就要求程序停止:
...
from signal import signal, SIGTERM
...
atexit.register(self.delpid)
signal(SIGTERM, lambda signum, stack_frame: exit(1))