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該腳本使用目前目錄中的檔案進行所有輸出。它有一個每秒列印“running”的循環。接收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)

相關內容