kill相关的信号简述

kill命令的原理

kill命令在linux中用来结束进程。但实际上,并不是kill杀死了进程,kill只是向内核发送了操作系统信号和进程标示号(PID),由内核负责处理需要结束的进程。
使用kill -l可以查看支持发送的信号:

1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX

这些信号的解释可以通过man 7 signal来查看。
kill除了测试程序遇到各种情况的退出状态,常用的其实只有三个:

  • 1) SIGHUP
    man pag中说是在控制终端上是挂起信号, 或者控制进程结束,动作是A表示缺省是结束进程

wiki百科

UNIX中进程组织结构为 session (会话)包含一个前台进程组及一个或多个后台进程组,一个进程组包含多个进程。一个session可能会有一个session首进程,而一个session首进程可能会有一个控制终端。一个进程组可能会有一个进程组首进程。进程组首进程的进程ID与该进程组ID相等。这儿是可能会有,在一定情况之下是没有的。与终端交互的进程是前台进程,否则便是后台进程。
SIGHUP会在以下3种情况下被发送给相应的进程:
1、终端关闭时,该信号被发送到session首进程以及作为job提交的进程(即用 & 符号提交的进程)
2、session首进程退出时,该信号被发送到该session中的前台进程组中的每一个进程
3、若父进程退出导致进程组成为孤儿进程组,且该进程组中有进程处于停止状态(收到SIGSTOP或SIGTSTP信号),该信号会被发送到该进程组中的每一个进程。
系统对SIGHUP信号的默认处理是终止收到该信号的进程。所以若程序中没有捕捉该信号,当收到该信号时,进程就会退出。

除此之外这个信号时可以被捕捉的,很多服务(Apache,Ngnix)将这个信号视为relaod,即重启。

关于这个信号有一个很有意思的命令:nohup。
这个命令就跟它的名字一样,这个命令的作用就是试通过它运行的进程完全忽略SIGHUP信号。一般而言,如果你以SSH等方式连接到远程主机,当你希望运行一些程序并且当你退出后依然能在后台运行的时候,除了at命令,你还可以使用nohup这个命令。 。
用法:

nohup COMMAND #前景工作
nohup COMMAND & #背景工作

测试:

nohup ping 127.0.0.1 &

nohup: 忽略输入并把输出追加到"nohup.out”

pgrep ping 

10363

ctrl+D
pgrep ping

10363

  • 9)SIGKILL
    这个信号一般被人称为杀死进程,简单来说就是内核收到该信号和进程的PID后,会立刻停止结束该进程。怎么个立即,后面会说。这个信号不能被捕获也不能被忽略

SIGKILL有几个特性需要注意:

僵尸进程不能被杀死,因为它们已经死亡,只等待它们的父进程回收它们。
处于阻塞状态的进程不会死亡,直到它们再次醒来。
init进程是特殊的:它不获得它不想处理的信号,因此它可以忽略SIGKILL。
因为SIGKILL不给进程任何在终止时做清理操作的机会,在大部分系统关闭过程中,在采取SIGKILL之前,使用信号SIGTERM使进程终止的尝试先被作出。
即使SIGKILL被发送给它,一个正在不可中断睡眠的进程也可能不会终止(并且释放它的资源)。这是少数几个一个UNIX系统可能需要被重新启动来解决临时软件问题的例子中的一个。

关于僵尸进程可以参考wiki,简单来说就是父进程没有wait/waitpid的已经结束的进程。

  • 15)SIGTERM
    这个信号与SIGKILL相似,但是更友好一些,也是kill默认发送的信号。这个信号可以被捕获,允许程序做一些清理工作,也可以允许一些重要的进程直接忽略信号,防止误杀。但是这个信号和你点击窗口的X号好像不是一回事。这个信号的特性是只有当前进程收到信号,子进程不会收到。如果当前进程被kill了,那么它的子进程的父进程将会是init,也就是pid为1的进程,换句话说这个操作容易产生孤儿进程。

你可能感兴趣的:(kill相关的信号简述)