kill && kill -9

测试kill和kill -9信号的区别。

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
* Powered by Jetbrains Clion.
* Created by 王乐.
* Date: 2018/8/25.
* FileName: kill.c.
*/

//***** Code is coming! *****//

#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <sys/time.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void sigHandler(int sig) {
printf("signo = %d\n", sig);
kill(getpid(), SIGKILL);
}

int main(int argc, char *argv[]) {

sigset_t signals;

signal(SIGINT, sigHandler);

// 置空信号集
sigemptyset(&signals);

// 将所有位置1,与上个函数相反
// sigfillset(&signals);

// 添加和删除信号。
sigaddset(&signals, SIGINT);
sigaddset(&signals, SIGQUIT);

// SIGKILL 进程不能被阻塞和拦截,该处阻塞无效
sigaddset(&signals, SIGKILL);

// 将集合中的信号加入到阻塞信号集中
sigprocmask(SIG_BLOCK, &signals, NULL);

sigset_t pending;
int i = 0;
int j = 1;
while (1) {
// 获取未决信号集
sigemptyset(&pending);
sigpending(&pending);

for (i = 1; i < 32; i++) {
if (sigismember(&pending, i) == 1) {
printf("1");
} else {
printf("0");
}
}
puts("");

if (j++ % 10 == 0) {
sigprocmask(SIG_UNBLOCK, &signals, NULL);
}

sleep(1);
}

return 0;
}

编译运行
按CTRL-C可以发送信号SIGINT。
按CTRL-\可以发送信号SIGQUIT。

发送完成可直接捕获到这两个信号。
我们可以使用man手册查看信号部分

1
man 7 signal

其中有一句话:
The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.

表示SIGKILL和SIGSTOP信号不能被捕获。

再查看信号的详细信息:
SIGKILL 9 Term Kill signal
SIGTERM 15 Term Termination signal

不难发现 信号9是kill信号,直接杀死该进程,而kill默认发送的信号SIGTERM则是kill命令(例:kill 1234)则默认发送15号信号。

15号信号可以被捕获到,而我们的程序捕获到15号信号之后可以做一些回收资源、打印日志等操作。
但当接收到信号9的时候,则直接被杀死,不会来得及释放内存,打印日志等。

综合来看,我们应尽量使用kill而不是kill -9.