我在嘗試時遇到了這個問題在 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)