在服务器运维以及程序开发过程中,经常会用到kill命令或者kill()方法。那么,kill是做什么以及信号0的作用又是什么,一起来探寻吧。
kill可以使用的信号
- [root@localhost ~]# 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
注意:
下面内容常作为面试题:前31个信号和后31个信号的区别?
在Linux上执行kill -l看到可使用信号共有62个(仔细看没有32、33哦)。
- 编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的)
- 编号为34 ~ 64的信号是后来扩充的,称做可靠信号(实时信号)
不可靠信号、可靠信号区别:前者不支持排队,可能会造成信号丢失,而后者不会。
kill的文档描述
通过man命令可以看到关于kill指令的描述以及参数解释,这里截取部分描述,如下:
- [root@localhost ~]# man 1 kill
- KILL(1) User Commands KILL(1)
- NAME
- kill - terminate a process
- SYNOPSIS
- kill [-s signal|-p] [-q sigval] [-a] [--] pid...
- kill -l [signal]
- DESCRIPTION
- The command kill sends the specified signal to the specified process or process group. If no signal is specified, the TERM signal is sent. The TERM signal
- will kill processes which do not catch this signal. For other processes, it may be necessary to use the KILL (9) signal, since this signal cannot be caught.
- Most modern shells have a builtin kill function, with a usage rather similar to that of the command described here. The '-a' and '-p' options, and the possi‐
- bility to specify processes by command name are a local extension.
- If sig is 0, then no signal is sent, but error checking is still performed.
- ......
- # [root@localhost ~]# man 2 kill
- KILL(2) Linux Programmer's Manual KILL(2)
- NAME
- kill - send signal to a process
- SYNOPSIS
- #include <sys/types.h>
- #include <signal.h>
- int kill(pid_t pid, int sig);
- Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
- kill(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
- DESCRIPTION
- The kill() system call can be used to send any signal to any process group or process.
- If pid is positive, then signal sig is sent to the process with the ID specified by pid.
- If pid equals 0, then sig is sent to every process in the process group of the calling process.
- If pid equals -1, then sig is sent to every process for which the calling process has permission to send signals, except for process 1 (init), but see below.
- If pid is less than -1, then sig is sent to every process in the process group whose ID is -pid.
- If sig is 0, then no signal is sent, but error checking is still performed; this can be used to check for the existence of a process ID or process group ID.
- For a process to have permission to send a signal it must either be privileged (under Linux: have the CAP_KILL capability), or the real or effective user ID of
- the sending process must equal the real or saved set-user-ID of the target process. In the case of SIGCONT it suffices when the sending and receiving processes
- belong to the same session.
从描述可知,无论是man 1文档还是man 2文档都指出:kill命令用于向指定的pid进程发送信号,进程在接收到对应的信号之后会进行对应的操作。
关于信号0的作用
man 1 文档中有一句 If sig is 0, then no signal is sent, but error checking is still performed, 意思是:如果sig为0,则不发送信号,但仍然进行错误检查。
man 2 文档中有一句 If sig is 0, then no signal is sent, but error checking is still performed; this can be used to check for the existence of a process ID or process group ID,意思是:如果sig为0,则不发送信号,但仍然进行错误检查; 这可以用来检查是否存在进程ID或进程组ID。
也就是说,kill -0 pid 执行时不会发送信号,但是会对pid对应进程做错误检查。如果返回0则进程、服务正在运行中;反之是其他值,则进程死了或者服务已停止。
信号0的用法
既然,信号kill -0 pid不发送信号,主要用于检查对应进程做错误检查。那么,在开发中我们就可以通过kill返回的错误信息来判断进程是否存在、正常运行。
shell脚本中示例:
- #!/bin/bash
- PIDFILE=$1
- if [ -f $PIDFILE ]; then
- PID="$(cat $PIDFILE)"
- if kill -0 "$PID" &> /dev/null; then
- echo "process is exists"
- exit 0
- else
- echo "process is not exists"
- exit 5
- fi
- fi
Go代码中示例:
- func processExists(pid int) bool {
- if err := syscall.Kill(pid, 0); err == nil {
- return true
- } else {
- return false
- }
- }
【编辑推荐】