信号
ps:不是信号量!
是一种软件中断,是一种事件通知机制,与事件一一对应;
每个信号对应的事件都不可以丢弃的信号是可靠信号否则为不可靠信号;
优先处理的是实时信号否则为非实时信号;
生命周期:
产生
硬件产生:ctrl+c / ctrl+z / ctrl+\
软件产生:kill命令(杀死进程的原理就是给进程发送了一个终止信号)
注册
让进程知道自己收到了某个信号;
在进程pcb中有一个pending位图(未决信号集合),当前进程收到但是还未处理的信号集合(二进制),信号的注册就是在该位图标记信号值对应位置为1;
pcb中还有一个sigqueue链表,收到信号后在这个链表中添加对应信号结点;
可靠信号的注册:不管当前是否有相同信号已经注册,都会位图置1,添加一个结点;
非可靠信号注册:如果相同信号没有注册则注册一下,已经注册则直接返回(可能导致信号丢失)。
注销
在处理之前将信号存在的痕迹抹除(先注销再处理);
将sigqueue链表中对应信号结点删除并修改位图;
可靠信号注销:删除一个结点,当所有该信号所有结点都被删除则修改位图;
非可靠信号注销:删除信号结点,位图置为0;
处理
调用该信号的处理函数;
处理方式;
①默认处理方式:系统中定义好的;
②忽略处理方式:啥都不干;
③自定义处理方式:用户自己定义处理函数替换掉系统中的处理方式。
自定义处理方式的信号捕捉流程:
①当程序在主控流程执行的时候,因为系统调用,中断,异常而进入内核态运行;
②在处理完内核功能之后,返回用户态之前,查看是否有信号待处理;
③忽略以及默认直接在内核态完成,如果自定义则返回用户态执行;
④当执行完自定义处理函数之后返回内核态;
阻塞
阻塞一个信号指的是暂时不去处理该信号;
pcb中有一个信号集合——block信号阻塞集合,在该集合中标记哪个信号就表示要阻塞哪个信号。
(一个进程内可以理解为有两个阻塞集合,一个是一个进程内所有pcb所共有的一个是单个pcb所独有的)
在信号中有两个比较特殊:SIGKILL -9 & SIGSTOP -19 ,这两个信号不会被阻塞阻塞,不会被忽略,不会被自定义,是无法修改的!(无法啥死僵尸进程)
应用
SIGCHLD & SIGPIPE
//SIGCHLD:子进程推出后通知父进程的信号;
signal(SIGCHLD, SIG_IGN);
//SIGPIPE:所有管道读端关闭后,继续write所触发的异常信号;
signal(SIGPIPE, SIG_IGN);