[Python] 在關閉 Linux terminal console 時讓 python 程式安全結束

[Python] 在關閉 Linux terminal console 時讓 python 程式安全結束

最近專案遇到一個問題,

某隻程式會負責啟動一些 daemon,並在資料庫中設定一些值

但就在這隻程式還在執行時,terminal console 被關掉了,

這時這隻程式和它叫起來的程式就全部一起消失不見了,

原本預期資料庫要設定完的值也沒有全部完成,導致了後續的問題…

 

要一堆 process 同時掛掉,想起來就是有 signal 在做怪…

查了一下,terminal console 關閉時,程式會收到 SIGHUP 這個 signal,

而預設的處理方式就是停止程式~

(參考 stackoverflow: Signals received by bash when terminal is closed)

 

在 shell 程式裡,可以用 trap 的方式決定收到 signal 時要做什麼事,

像是下面的程式會在收到 signal 時,在 log.txt 裡寫出收到的 signal number,

而不會結束程式::

i=0; while((++i<32));
do
    trap "echo received signal $i >> log.txt" $i;
done

 

python 裡也可以設定收到 signal 時要做什麼事, 

參考 python doc: signal,可以用 signal.signal() 函式來設定 signal handler 函式,

例如下面的程式就是在收到 SIGHUP 的時候,

raise 一個 KeyboardInterrupt exception~

因為我想讓「使用者按下 Ctrl-C 來中止程式」和「按下 terminal console 的關閉按鈕」都做同樣的事情,

這樣我就都只要處理 KeyboardInterrupt exception 就行了:: 

import signal
def _signal_handler(signum, frame):
print "Received signal %s, stop execution!" % ({signal.SIGHUP: "SIGHUP"}.get(signum, str(signum))))
raise KeyboardInterrupt()
# Register signal handler to handle SIGHUP signal
signal.signal(signal.SIGHUP, _signal_handler)

 

不過要注意的是,註冊 signal handler 只會影響到自己這隻程式,

其他被自己叫起來的 process 也是會收到 SIGHUP,因此他們都會掛掉,

除非你也對他們做處理囉~

 

(本頁面已被瀏覽過 318 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料