关闭 Python 守护进程时运行代码

Bas*_*asj 2 python linux daemon python-daemon

我正在使用此处此处引用的著名代码在 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()
Run Code Online (Sandbox Code Playgroud)

问题是在调用时./myscript.py stop,因此daemon.before_stop()不再引用self.blah!

AttributeError: 测试实例没有属性 'blah'

因此,使用这种守护进程方法,在停止守护进程之前不可能访问守护进程的变量......

问题:之前如何访问守护进程类的变量:

  • 止于 ./myscript.py stop

  • 被 SIGTERM 停止

  • (被杀?)


编辑:解决了,这是一个带有quit()方法的工作守护程序代码。

Ser*_*sta 5

守护进程代码向守护进程发送一个 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)
Run Code Online (Sandbox Code Playgroud)

但这还不够!Python 标准库文档说atexit

当程序被 Python 未处理的信号杀死时,不会调用通过此模块注册的函数

由于该进程预计会收到 SIGTERM 信号,因此您必须安装一个处理程序。如一个活动状态配方所示,它非常简单:只要程序收到信号就停止:

...
from signal import signal, SIGTERM
...

atexit.register(self.delpid)
signal(SIGTERM, lambda signum, stack_frame: exit(1))
Run Code Online (Sandbox Code Playgroud)