在 Ubuntu 16.04 上使用 systemd 进行 SIGKILL/shutdown 之前没有 SIGTERM

在 Ubuntu 16.04 上使用 systemd 进行 SIGKILL/shutdown 之前没有 SIGTERM

我在尝试时遇到了这个问题在 Stackoverflow 上回答问题

在关机时,Ubuntu 12.04 会SIGTERM向所有进程发送 并等待最多 10 秒,然后使用 终止它们SIGKILL(除非它们之前已终止)。我在 SO 上的回答甚至包含一个 Python 脚本来验证该行为。该脚本在终端中启动,发送到后台,然后由终端放弃。当收到 时SIGTERM,脚本会继续运行并不断将其运行时间打印到文件中接收SIGTERM

然而,在 Ubuntu 16.04 中,脚本在关机时会被立即终止(没有SIGTERM记录)。

我谷歌搜索了一段时间,但没有找到任何有用的东西。没有人遇到过当前 LTS 版本的重大变化吗?

以下是脚本signaltest.py

import signal
import time

stopped = False

out = open('log.txt', 'w')

def stop(sig, frame):
    global stopped
    stopped = True
    out.write('caught SIGTERM\n')
    out.flush()

signal.signal(signal.SIGTERM, stop)

while not stopped:
    out.write('running\n')
    out.flush()
    time.sleep(1)

stop_time = time.time()
while True:
    out.write('%.4fs after stop\n' % (time.time() - stop_time))
    out.flush()
    time.sleep(0.1)

log.txt该脚本使用当前目录中的文件进行所有输出。它有一个循环,每秒打印一次“正在运行”。接收SIGTERM会中断循环并启动另一个循环,该循环打印自接收以来经过的秒数SIGTERM

该脚本从分离的终端运行,使用disown

python signaltest.py &
disown

需要明确的是:这不是重复的Ubuntu 在关机时不发送 SIGTERM。问题是关于桌面应用程序的,答案也不太合适。

答案1

systemd (与早期 Ubuntu 版本中的 upstart 相反) 在关机时还会发送 SIGHUP (并等待 90 秒而不是 10 秒后再发送SIGKILL)。我建议忽略SIGHUP或以相同 (幂等) 方式SIGTERM处理。SIGHUP

修改后的测试脚本可以改成这样:

import signal
import time

stopped = False

out = open('log.txt', 'w')

def stop(sig, frame):
    global stopped
    stopped = True
    out.write('caught SIGTERM\n')
    out.flush()

def ignore(sig, frsma):
    out.write('ignoring signal %d\n' % sig)
    out.flush()

signal.signal(signal.SIGTERM, stop)
signal.signal(signal.SIGHUP, ignore)

while not stopped:
    out.write('running\n')
    out.flush()
    time.sleep(1)

stop_time = time.time()
while True:
    out.write('%.4fs after stop\n' % (time.time() - stop_time))
    out.flush()
    time.sleep(0.1)

相关内容