1.什么是信号
信号是一种实现进程间异步的通知机制,用来提醒进程一个事件已经发生。 linux系统响应某些状况而产生的事件,进程在接受到信号会采取相应的动作。
2.查看所有信号命令
kill -l
3.信号处理方式
(1)忽略
(2)捕获并处理(自定义处理函数)
(3)缺省处理(默认处理)
需要注意的是,9号SIGKILL,19号SIGSTOP信号不能忽略、不可捕获处理。
4.注册信号(即信号处理方式(2)自定义处理方式)
信号注册函数:
函数原型:void(*signal(int signum, void(*pf)(int))) 即signal是一个函数,2个参数(一个整形代表信号,一个函数指针代表自定义处理函数),返回值类型为一个函数指针,即旧的信号处理函数。
代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <signal.h>
4
5 //自定义处理信号函数
6 void handler(int s)
7 {
8 printf("我是信号\n");
9 }
10 int main()
11 {
12 //注册一个信号,(信号来了按照自定义的处理方式处理)
13 signal(SIGINT, handler);
14
15 for(;;)
16 {
17 printf("正常流\n");
18 sleep(1);
19 }
20 return 0;
21 }
另外:子进程继承父进程的信号处理方式:
代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <signal.h>
4
5 //注册自己的信号处理方式函数
6 void handler(int s)
7 {
8 printf("我是信号\n");
9 }
10 int main()
11 {
12 __sighandler_t old;//接受旧的信号处理函数的函数指针
13 old=signal(SIGINT, handler);
14
15 if(old==SIG_ERR)
16 {
17 printf("signal err");
18 exit(1);
19 }
20 //子进程
21 if(fork()==0)
22 {
23 for(;;)
24 {
25 printf("我是子进程\n");
26 sleep(1);
27 }
28 }
29 else//父进程
30 {
31 while(getchar()!='\n')
32 {;}
33
34 signal(SIGINT, old);
35
36 for(;;)
37 {
38 printf("我是父进程\n");
39 }
40 }
41 return 0;
42 }
以上案例,当子进程执行时,打印出我是子进程,此时给一个ctrl+c信号,会打印我是信号,这就说明这个信号处理方式是继承来自父进程的注册的信号,而键盘输入 \n,会激活父进程,这时将信号处理方式切回原来的信号处理方式,即默认退出,这时给一个信号ctrl+c,会使得父进程按照旧的信号处理方而退出,这时只剩下子进程,成为孤儿进程,被系统的1号进程所收养,此时再给它一个ctrl+c信号,由于孤儿进程无法接受终端发给的信号,因此信号无法处理,子进程一直运行(相当于忽略此信号),只有在另一终端使用kill 子进程号 来终止此进程,(进程号通过命令 ps -ef | grep a.out | grep -v grep 来获取)