我在尝试时遇到了这个问题在 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)