在沒有訊號處理程序的情況下,SIGTERM 的行為是否與 SIGKILL 相同?

在沒有訊號處理程序的情況下,SIGTERM 的行為是否與 SIGKILL 相同?

大多數 SIGTERM 和 SIGKILL 的描述都指出 SIGKILL,

與 SIGTERM 和 SIGINT 相比,[...] 不能被捕獲或忽略 [...] (維基百科

這是 SIGTERM 和 SIGKILL 之間的唯一區別嗎?特別是,如果進程沒有安裝 SIGTERM 處理程序,向進程發送 SIGTERM 或 SIGKILL 之間有什麼區別嗎?

答案1

在沒有任何訊號配置的情況下,SIGTERMSIGKILL至少從被終止進程的角度來看實際上是等效的,預設操作是終止進程的其他訊號也是如此,包括SIGUSR1SIGUSR2。作為伊爾卡丘指出,父進程被告知終止子進程的訊號(這就是你的 shell 區分訊號的方式,並列印例如“終止”v.“使用者定義訊號 1”)。

正如維基百科上提到的,SIGKILLcan’t be returned orignored,而SIGTERMcan;請注意,這意味著進程不需要安裝處理程序即可SIGTERM無效,它可以簡單地阻止它或忽略它(請參閱sighold()sigrelse()sigignore())。

POSIX 的詳細部分訊號處理背後的基本原理。 Linuxsignal(7)線上幫助頁也詳細記錄了訊號。

答案2

這是 SIGTERM 和 SIGKILL 之間的唯一區別嗎?

不。

SIGKILLa和 uncaught之間的一個很大的區別SIGTERM是前者也會醒來一個停止的進程(因此它可以立即銷毀自己),而後者僅在SIGCONT.

簡單的例子:

$ sleep 1000 & sleep 1; kill -TSTP $!
[1] 6455

[1]+  Stopped                 sleep 1000
$ kill -TERM 6455
$ jobs
[1]+  Stopped                 sleep 1000
$ kill -CONT 6455
$ jobs
[1]+  Terminated              sleep 1000

如果您想確保您的TERMHUPINT等訊號有任何效果,您應該將其與CONT訊號配對(以任何順序)。

人們可能不容易理解這一點,因為 bash 內建函數的魔力kill——當與作業 id 一起使用時,如%%1(或否定 pid)指的是已停止的進程工作, 它會自己做這一切窗簾後面:

/* Give PID SIGNAL.  This determines what job the pid belongs to (if any).
   If PID does belong to a job, and the job is stopped, then CONTinue the
   job after giving it SIGNAL.  Returns -1 on failure.  If GROUP is non-null,
   then kill the process group associated with PID. */
int
kill_pid (pid, sig, group)

相關內容