Process
kill -9 $PPID 殺死程序?
我讀到殺死父程序將使子程序附加到init(PPID = 1)。
為了測試這一點,我創建了三個 shell 並向第二個發送了終止信號:
# first process "a" a$sh # second process "b" sh-5.0$ PS1=b$ b$sh # thrid process "c" sh-5.0$ PS1=c$ # killing process "b" c$kill -9 $PPID c$Killed a$exit a$
(killed和exit都列印到螢幕上,不輸入)
但是第三個 shell 也被殺死了,而不是附加到 init 上。為什麼和由誰?
我將重新創建您的實驗:
# First shell $ echo $$ 41903 # Start the second shell $ bash $ echo $$ $PPID 41934 41903 # Start the third shell $ bash $ echo $$ $PPID 41938 41934
現在,在第二個終端中,我將使用它
strace
來監視第三個 shell 執行的系統呼叫和處理的信號。請注意,shell 在等待輸入時被阻塞:$ strace -p 41938 strace: Process 41938 attached pselect6(1, [0], NULL, NULL, NULL, {[], 8}) = 1 (in [0])
在第三個終端中,我將殺死第二個 shell(我正在跟踪的那個的父級):
$ kill -9 41934
此時,我在輸出中沒有觀察到任何東西
strace
——第三個 shell 仍在執行。現在,如果我嘗試在第一個終端中輸入內容,我會在
strace
輸出中看到以下內容:read(0, 0x7ffd6879ebbf, 1) = -1 EIO (Input/output error) ... write(2, "exit\n", 5) = 5 ... setpgid(0, 41938) = 0 exit_group(0) = ?
第三個 shell 未能從標準輸入(文件描述符 0——
read
在這種情況下為第一個參數)讀取並自行終止。殺死父程序似乎以某種方式改變了終端設備的狀態,導致子程序read()
失敗。讓我們重複這個實驗,但這次跟踪第一個 shell——我將要殺死的程序的父程序。
$ echo $$ 48134 $ bash $ echo $$ $PPID 48163 48134 $ bash $ echo $$ $PPID 48169 48163
在一個單獨的終端中,跟踪第一個 shell:
$ strace -p 48134 strace: Process 48134 attached wait4(-1,
在另一個終端中,殺死第二個 shell:
$ kill -9 48163
原來的貝殼對它的孩子的死做了什麼反應?
wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGKILL}], WSTOPPED|WCONTINUED, NULL) = 48163 rt_sigprocmask(SIG_BLOCK, [CHLD TSTP TTIN TTOU], [CHLD], 8) = 0 ioctl(255, TIOCSPGRP, [48134]) = 0
注意
ioctl()
帶有TIOCSPGRP
參數的呼叫。當第一個 shell 注意到它的子程序終止時,它會將終端的前台程序組 ID 改回它自己(注意 fd 255 也是終端設備的打開文件描述符)。這就是導致read()
第三個 shell 失敗的原因——它試圖從設備中讀取,但不在前台程序組中。