6

我有一个在 Debian 上运行的单线程 Python 2.7 守护程序/服务。我有一些禁用某些硬件功能的关键清理代码。

import sys
import atexit
import signal
from my_job import give_high_fives
from my_cleanup import prevent_the_apocalypse

atexit.register(prevent_the_apocalypse)
signal.signal(signal.SIGTERM, prevent_the_apocalypse)
signal.signal(signal.SIGHUP, prevent_the_apocalypse)
try:
    while True:
        give_high_fives()
finally:
    prevent_the_apocalypse()

这看起来很偏执,而且我也不喜欢这么多次调用清理代码。现在看起来清理在SIGTERM.

prevent_the_apocalypse在所有可能的退出条件中是否有一种方法可以精确地一次?

4

2 回答 2

6

在 Python 中编写一个正确的守护进程是很困难的。事实上,用任何语言都很难。PEP 3143解释了这些问题。

daemon模块包含了大部分细节,因此您不必正确处理它们。如果你使用它,添加清理代码变得非常容易。

一种选择是子类化daemon.DaemonContext并将其放在那里。例如:

class MyDaemonContext(daemon.DaemonContext):
    def close(self):
        if not self.is_open:
            return
        prevent_the_apocalypse()
        super(MyDaemonContext, self).close()

with MyDaemonContext():
    while True:
        give_high_fives()

daemon模块已经设置了信号处理程序,以便它们执行您配置它们执行的操作,但不会跳过该close方法。(close将只运行一次——在上下文中__exit__,在atexit方法中,或者可能在其他地方,视情况而定。)

如果您想要更复杂的东西,其中一些信号跳过close而另一些则不跳过,而不是子类化,只需signal_map适当地设置它。

于 2013-10-09T17:50:13.863 回答
-1

让您的信号处理程序只将全局变量设置为 true。然后在你的主循环中检查那个变量,如果它是真的,在你退出时运行你的清理处理程序。

于 2013-10-09T17:51:26.670 回答