一.信号的基本概念
1.概念:信号其实通俗的来说就是操作系统与进程之间某些事件发生的一种通知机制。
2.信号的产生由随机性------异步。
3.要能够识别信号的前提条件是你认识信号。
4.在信号还没有产生的时候,其实你也知道它该怎样处理,你是识别它的。
5.我们为什么能够识别信号,因为大部分场景,我们都是见过的,其实就是大部分信号我们都是认识的。
6.信号是给进程发送的,进程想要处理信号就必须首先要识别信号。
7.进程接收信号之后,不是要马上就处理信号,而是先把信号记录下来,等到合适的时候处理。
8.进程是怎样记录信号,并识别它?
1)信号一共有62个,但是平常的话就只学前31个
2)宏是大写的,但是在计算机中就是数字。
3)进程的PCB中必须要维护一个位图,比特位的位置代表信号的编码,比特位的内容代表的是有还是没有。收到信号的时候,进程中的PCB检测自己的位图列表,然后通过比特位将0置为1。
4)产生信号的方式有很多种,但是执行的话只能通过操作系统。(操作系统是进程的管理者)
5)操作系统向进程发送信号的过程:
先找到进程的PCB,然后找到它的位图,根据信号的编码将对应的比特位由0置为1。
6)操作系统发信号的这个说法并不准确,应该是操作系统写信号,修改信号的比特位。
二.信号产生的一般方式
1.用户输入命令,在shell下启动一个前台进程
用户按"ctrl ^c"这个键盘输入产生一个硬件中断,被操作系统(OS)获取,解释为信号,发送给目标前台进程,前台进程因为受到信号,进而引起进程的退出。(ctrl ^c是二号信号)
进程收到信号之后有三种处理方式:
1)忽略此信号
2)执行此信号的默认处理动作。
3)提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数。这种方式称作捕捉一个信号。(Catch)
处理信号的第三种方式有一个函数signal-------用来自定义和捕捉的
typedef void(* sighandler_t)(int);
sighandler_t signal (int signum, sighandler_t handler)
signal函数有两个参数:一个是int,一个是sighandler_t ,返回值也是sighandler_t ,
该指针指向一个参数为int,无返回值的函数。第一个参数是信号的编号,第二个参数是信号的处理方法。
修改信号的默认行为
//自定义捕捉信号
#include<iostream>
#include<signal.h>
#include<unistd.h>
void handler(int signo)
{
printf("catch sig,signo : %d\n",signo);
exit(1);
}
int main()
{
int i = 1;
while(i <= 31)
{
signal(i,handler);
i++;
}
while(1)
{
printf("hello world\n");
sleep(1);
}
}
//18 19号信号不会被修改。9号信号非常的强势,它的性能依然存在。
//忽略信号 ---- SIG_IGN