我先抛出如下问题:
杀死了父进程后,子进程也会被杀死吗?
你了解进程组吗?
请你先思考下。再看结论:
graph TB
a[kill 父进程] -->b{父进程 ID 和进程组 ID 是否相同?}
b -->|是| c[父进程和子进程都会被 kill]
b -->|否| d[父进程会被 kill, 但是子进程不一定会被 kill]
c --> e[通过 kill 进程组可以 kill 父进程和全部子进程]
d --> e
classDef mainStep fill:#02d7f2,color:#000
class e mainStep
杀死父进程并不会同时杀死子进程 启动进程模拟 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 $ sleep 300 & [1] 19307 $ sleep 300 & [2] 19317 $ ps j -A | egrep -i 'PGID|sleep' | cut -c 1-200 USER PID PPID PGID SESS JOBC STAT TT TIME COMMAND ganzhixiong 19307 18589 19307 0 1 SN s010 0:00.00 sleep 300 ganzhixiong 19317 18589 19317 0 1 SN s010 0:00.00 sleep 300 ganzhixiong 19332 18589 19331 0 3 S+ s010 0:00.00 egrep -i PGID|sleep $ ps -fp 18589 UID PID PPID C STIME TTY TIME CMD 501 18589 18585 0 10:43PM ttys010 0:02.52 -zsh $ sudo kill -9 18589 [进程已完成]
用 Node.js 应用演示 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 $ ps jf -A | egrep -i 'PGID|homens' PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 24536 26167 26166 24536 pts/0 26166 S+ 1000 0:00 | \_ grep -E --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox -i PGID|homens 1 18911 18907 16898 ? -1 Sl 0 0:00 node /ktt/NewNS/YS-LoraHomeNS/app.js 18911 18927 18907 16898 ? -1 Sl 0 3:58 \_ /ktt/common/download/node-v6.9.2-linux-x64/bin/node /ktt/NewNS/YS-LoraHomeNS/app.js 18927 18946 18907 16898 ? -1 Sl 0 0:35 | \_ /ktt/common/download/node-v6.9.2-linux-x64/bin/node /ktt/NewNS/YS-LoraHomeNS/lib/dispatcher/ThreadLogicDispatcher Main.BJ.KTT/1 18911 18928 18907 16898 ? -1 Sl 0 0:00 \_ /ktt/common/download/node-v6.9.2-linux-x64/bin/node /ktt/NewNS/YS-LoraHomeNS/lib/schedule/Dispatcher/handler Main.BJ.KTT/Master 18911 18991 18907 16898 ? -1 Sl 0 0:01 \_ /ktt/common/download/node-v6.9.2-linux-x64/bin/node /ktt/NewNS/YS-LoraHomeNS/lib/Weather/index Main.BJ.KTT/Master $ sudo kill -TERM 18911 [sudo] password for admin: $ ps jf -A | egrep -i 'PGID|homens' PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 24536 26326 26325 24536 pts/0 26325 S+ 1000 0:00 | \_ grep -E --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox -i PGID|homens 1 18928 18907 16898 ? -1 Sl 0 0:00 /ktt/common/download/node-v6.9.2-linux-x64/bin/node /ktt/NewNS/YS-LoraHomeNS/lib/schedule/Dispatcher/handler Main.BJ.KTT/Master 1 18991 18907 16898 ? -1 Sl 0 0:01 /ktt/common/download/node-v6.9.2-linux-x64/bin/node /ktt/NewNS/YS-LoraHomeNS/lib/Weather/index Main.BJ.KTT/Master
通过以上结果,可以得出如下结论:当结束父进程时,并不一定会结束所有的子进程。
进程组 进程组用 PGID 表示 。进程组是一个或多个进程(通常与一个作业关联)的集合,可以从同一个终端接收信号。
从上面 Node.js 应用,可以得知该进程组 ID 为 18907。 下面我再举例说明:
1 2 3 4 5 $ ps j USER PID PPID PGID SESS JOBC STAT TT TIME COMMAND ganzhixiong 24846 19638 24846 0 2 SN s010 0:00.00 tail -f /var/log/system.log ganzhixiong 24847 19638 24846 0 2 SN s010 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn CRON
可以发现 tail
和 grep
的 PGID 是相同的。
通过结束进程组来结束进程及其全部子进程
我们用一个负数 -18907
向进程组发送信号。如果我们传递的是一个正数,这个数将被视为进程 ID 用于终止进程。如果我们传递的是一个负数,它被视为 PGID,用于终止整个进程组。
参考