进程的管理主要是指进程的关闭与重启。我们一般关闭或重启软件,都是关闭或重启它的程序,而不是直接操作进程的。比如,要重启 apache 服务,一般使用命令"service httpd restart"重启 apache的程序。然而我们也可以通过直接管理进程来关闭或重启 apache ,这时就要依赖进程的信号(Signal)了。我们需要给予该进程号,告诉进程我们想要让它做什么。
系统中可以识别的信号较多,我们可以使用命令"kill -l"或"man 7 signal"来查询。命令如下:
[root@CncLucZK ~]# 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
信号代号 | 信号名称 | 说 明 |
---|---|---|
1 | SIGHUP | 该信号让进程立即关闭.然后重新读取配置文件之后重启 |
2 | SIGINT | 程序中止信号,用于中止前台进程。相当于输出 Ctrl+C 快捷键 |
8 | SIGFPE | 在发生致命的算术运算错误时发出。不仅包括浮点运算错误,还包括溢出及除数为 0 等其他所有的算术运算错误 |
9 | SIGKILL | 用来立即结束程序的运行。本信号不能被阻塞、处理和忽略。般用于强制中止进程 |
14 | SIGALRM | 时钟定时信号,计算的是实际的时间或时钟时间。alarm 函数使用该信号 |
15 | SIGTERM | 正常结束进程的信号,kill 命令的默认信号。如果进程已经发生了问题,那么这 个信号是无法正常中止进程的,这时我们才会尝试 SIGKILL 信号,也就是信号 9 |
18 | SIGCONT | 该信号可以让暂停的进程恢复执行。本信号不能被阻断 |
19 | SIGSTOP | 该信号可以暂停前台进程,相当于输入 Ctrl+Z 快捷键。本信号不能被阻断 |
这些常见的进程信号中最重要的就是 “1”、“9”、"15"这三个信号,我们只需要记住这三个信号即可。
把这些信号传递给进程,从而控制这个进程,这就需要使用 kill、killall 以及 pkill 命令
[root@localhost ~]# kill [信号] PID
信号编号 | 信号名 | 含义 |
---|---|---|
0 | EXIT | 程序退出时收到该信息。 |
1 | HUP | 挂掉电话线或终端连接的挂起信号,这个信号也会造成某些进程在没有终止的情况下重新初始化。 |
2 | INT | 表示结束进程,但并不是强制性的,常用的 “Ctrl+C” 组合键发出就是一个 kill -2 的信号。 |
3 | QUIT | 退出。 |
9 | KILL | 杀死进程,即强制结束进程。 |
11 | SEGV | 段错误。 |
15 | TERM | 正常结束进程,是 kill 命令的默认信号。 |
需要注意的是,表中省略了各个信号名称的前缀 SIG,也就是说,SIGTERM 和 TERM 这两种写法都对,kill 命令都可以理解。
[root@CncLucZK ~]# service httpd start #启动RPM包默认安装的apache服务
#查看 httpd 的进程树及 PID。grep 命令査看 httpd 也会生成包含"httpd"关键字的进程,
#也可以使用“-v”反向选择包含“grep”关键字的进程,grep -v "grep"
#这里使用 pstree 命令来查询进程,当然也可以使用 ps 和 top 命令
[root@CncLucZK ~]# pstree -p | grep "httpd"
|-httpd(1229312)-+-httpd(1229313)
| |-httpd(1229314)-+-{httpd}(1229317)
| | |-{httpd}(1229319)
| | |-{httpd}(1229320)
| | |-{httpd}(1229321)
| | |-{httpd}(1229322)
| | |-{httpd}(1229323)
...
[root@CncLucZK ~]# kill 1229320
#杀死PID是1229320的httpd进程,默认信号是15,正常停止
#如果默认信号15不能杀死进程,则可以尝试-9信号,强制杀死进程
[root@CncLucZK ~]# pstree -p | grep "httpd"
|-httpd(1229312)-+-httpd(1229313)
| |-httpd(1229315)-+-{httpd}(1229333)
| | |-{httpd}(1229413)
| | |-{httpd}(1229414)
| | |-{httpd}(1229415)
| | |-{httpd}(1229416)
| | |-{httpd}(1229417)
#PID是1229320的httpd进程消失了
[root@CncLucZK ~]# kill -1 1229312
使用“-1 (数字1)”信号,让httpd的主进程重新启动
[root@CncLucZK ~]# pstree -p |grep httpd
|-httpd(1229312)-+-httpd(1234513)
| |-httpd(1234514)-+-{httpd}(1234524)
| | |-{httpd}(1234575)
| | |-{httpd}(1234577)
| | |-{httpd}(1234579)
| | |-{httpd}(1234580)
| | |-{httpd}(1234582)
#子httpd进程的PID都更换了,说明httpd进程已经重启了一次
[root@CncLucZK ~]# vi tmp.sh #使用vi命令编辑一个文件,不要退出
#另开一个终端Shell,查看一下这个进程的状态。进程状态是S(休眠)和+(位于后台),因为是在另一个终端运行的命令
[root@CncLucZK ~]# ps aux |grep 'vi' #| grep -v "grep"
root 2064 0.5 3.3 1058976 63628 ? Sl Oct19 50:34 /usr/local/qcloud/YunJing/YDEyes/YDService
root 1235164 0.0 0.3 38000 5820 pts/0 S+ 13:43 0:00 vi /test/tmp.txt
root 1235305 0.0 0.0 12112 1072 pts/1 S+ 13:44 0:00 grep --color=auto vi
[root@CncLucZK ~]# kill -19 1235164
#使用-19信号,让PID为1235164的进程暂停。相当于在vi界面按 Ctrl+Z 快捷键
[root@CncLucZK ~]# ps aux |grep 'vi'
root 2064 0.5 3.3 1058976 61980 ? Sl Oct19 50:35 /usr/local/qcloud/YunJing/YDEyes/YDService
root 1235164 0.0 0.3 38000 5820 pts/0 T 13:43 0:00 vi /test/tmp.txt
root 1235780 0.0 0.0 12112 980 pts/1 R+ 13:47 0:00 grep --color=auto vi
#注意1235164进程的状态,变成了 T(暂停)状态。这时切换回vi的终端,发现vi命令已经暂停,又回到了命令提示符,不过1235164进程就会卡在后台。如果想要恢复,可以使用"kill -9 1235164”命令强制中止进程,也可以利用后续章节将要学习的工作管理来进行恢复
kill 命令并不一定会终止一个进程,kill 命令只是“发送”一个信号,因此,只有当信号被程序成功“捕获”,系统才会执行 kill 命令指定的操作;反之,如果信号被“封锁”或者“忽略”,则 kill 命令将会失效。
[root@localhost ~]# killall [选项] [信号] 进程名
注意,此命令的信号类型同 kill 命令一样,此命令常用的选项有如下 2 个:
杀死 httpd 进程。
[root@CncLucZK ~]# service httpd start #启动RPM包默认安装的apache服务
[root@CncLucZK ~]# ps aux | grep httpd #查看httpd进程
root 1229312 0.0 0.6 274556 11408 ? Ss 13:06 0:01 /usr/sbin/httpd -DFOREGROUND
apache 1234513 0.0 0.4 287632 8280 ? S 13:40 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1234514 0.0 0.6 1803832 12052 ? Sl 13:40 0:05 /usr/sbin/httpd -DFOREGROUND
apache 1234515 0.0 0.6 1803832 12052 ? Sl 13:40 0:05 /usr/sbin/httpd -DFOREGROUND
apache 1234516 0.0 0.7 1934976 14104 ? Sl 13:40 0:05 /usr/sbin/httpd -DFOREGROUND
apache 1238155 0.0 0.9 1803832 18172 ? Sl 14:04 0:04 /usr/sbin/httpd -DFOREGROUND
root 1312057 0.0 0.0 12112 1072 pts/0 S+ 22:45 0:00 grep --color=auto httpd
[root@CncLucZK ~]# killall httpd #杀死所有进程名是httpd的进程
[root@CncLucZK ~]# ps aux | grep httpd
root 1312110 0.0 0.0 12112 964 pts/0 S+ 22:46 0:00 grep --color=auto httpd
#查询发现所有可执行的httpd服务进程都消失了
[root@CncLucZK ~]# service httpd start
Redirecting to /bin/systemctl start httpd.service
[root@CncLucZK ~]# ps aux | grep httpd
root 1312670 0.0 0.5 274556 10956 ? Ss 22:50 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1312671 0.0 0.4 287292 8440 ? S 22:50 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1312672 0.0 0.6 1803828 12040 ? Sl 22:50 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1312673 0.0 0.7 1934956 13900 ? Sl 22:50 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1312674 0.0 0.9 1803828 18200 ? Sl 22:50 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1312960 0.0 0.8 1803828 16160 ? Sl 22:50 0:00 /usr/sbin/httpd -DFOREGROUND
root 1313748 0.0 0.0 12112 1084 pts/0 S+ 22:55 0:00 grep --color=auto httpd #pts/0是登陆终端
[root@CncLucZK ~]# killall -i httpd #交互式杀死httpd进程
Kill httpd(1312670) ? (y/N) n #这个进程是httpd的服务进程,如果杀死,那么就无法访问web服务
Kill httpd(1312671) ? (y/N) n
Kill httpd(1312672) ? (y/N) n
Kill httpd(1312673) ? (y/N) n
Kill httpd(1312674) ? (y/N) n
Kill httpd(1312960) ? (y/N) n
httpd: no process found
[root@localhost ~]# pkill [信号] 进程名
信号编号 | 信号名 | 含义 |
---|---|---|
0 | EXIT | 程序退出时收到该信息。 |
1 | HUP | 挂掉电话线或终端连接的挂起信号,这个信号也会造成某些进程在没有终止的情况下重新初始化。 |
2 | INT | 表示结束进程,但并不是强制性的,常用的 “Ctrl+C” 组合键发出就是一个 kill -2 的信号。 |
3 | QUIT | 退出。 |
9 | KILL | 杀死进程,即强制结束进程。 |
11 | SEGV | 段错误。 |
15 | TERM | 正常结束进程,是 kill 命令的默认信号。 |
[root@CncLucZK ~]# pkill -9 httpd #按名称强制杀死 httpd 进程
[root@CncLucZK ~]# ps aux | grep httpd #查看 apache 进程,发现没有了
root 1314255 0.0 0.0 12112 1044 pts/0 S+ 22:59 0:00 grep --color=auto httpd
[root@CncLucZK ~]# service httpd start #重新启动 apache 进程
Redirecting to /bin/systemctl start httpd.service
[root@CncLucZK ~]# ps aux | grep httpd #再次查看,apache 进程重新启动
root 1314292 0.7 0.5 274556 11164 ? Ss 22:59 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1314293 0.0 0.4 287292 8240 ? S 22:59 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1314294 0.0 0.9 1934956 18164 ? Sl 22:59 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1314295 0.0 0.6 1803828 12040 ? Sl 22:59 0:00 /usr/sbin/httpd -DFOREGROUND
apache 1314296 0.0 0.7 1803828 14076 ? Sl 22:59 0:00 /usr/sbin/httpd -DFOREGROUND
root 1314531 0.0 0.0 12112 1080 pts/0 S+ 22:59 0:00 grep --color=auto httpd
[root@localhost ~]# pkill [-t 终端号] 进程名
[-t 终端号] 选项用于按照终端号踢出用户;
[root@CncLucZK ~]# w #使用w命令查询本机已经登录的用户
23:03:48 up 6 days, 9:33, 1 user, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root ttyl - 19:47 18:52 0.01s 0.01s -bash
root pts/0 192.168.0.100 19:47 0.00s 0.09s 0.04s w
root pts/1 192.168.0.100 19:51 14:56 0.02s 0.02s -bash
#当前主机已经登录了三个root用户,一个是本地终端ttyl登录,另外两个是从192.168.0.100登陆的远程登录
[root@CncLucZK ~]# pkill -9 -t pts/1
#强制杀死从pts/1虚拟终端登陆的进程
[root@CncLucZK ~]# w
23:04:20 up 30 min, 2 users, load average: 0.00, 0.00,0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root ttyl - 19:47 21:27 0.01s 0.01s -bash
root pts/0 192.168.0.100 19:47 0.00s 0.06s 0.00s w
#虚拟终端pts/1的登录进程已经被杀死了
参考文献:
Linux kill命令详解:终止进程