信号:
作用:为了通知我们某个事件的发生
就是一个软中断,通知进程发生某件事情,打断进程当前的操作,去先处理这个事件
必须认识信号,信号不是立即处理的。而实现记录下来,选择一个合适的事机处理
信号必须有默认的处理方式,当然也可以改变。信号是可以被阻塞,暂时不处理
信号的周期性:生命周期:产生》》注册》》注销》》处理
linux信号的种类:kill -l 62个--两类(可靠/非可靠 实时/非实时)
产生:硬件中断:程序异常;软件中断(kill raise abort alarm sigqueue)
coredup:程序异常崩溃时记录运行数据;调试;ulimit -c,
注册:添加节点
分为可靠信号的注册:不管信号的位图是否为1,(信号是否注册)都要添加一个新的节点
与非可靠信号的注册:若位图为1,代表信号已经注册过了,因此什么都不做(第二次到来的信号丢弃)
注销:删除节点,位图置0
分为可靠信号的注销:删除节点,若仍有相同信号的节点,就不修改位图k,否则将位图置0
非可靠信号的注销:删除节点,位图直接置0
处理:默认 忽略 自定义 (signal sigaction) 信号的捕捉流程--》信号被注册后如何处理(针对自定义信号)
信号是再进程从内核态运行返回用户态的时候,进行处理的;
阻塞:暂时阻塞信号被递达;pcb中有一个blocked信号位图,这个位图用于标记有哪些信号被阻塞
task_struct 中有一个sigset_ blocked 位图与pending进行异或,就能将被处理的信号找出来
从pening中拿出信号,再在blocked中看一下是否被处理
信号的递达:一个动作,描述的是信号的处理
信号的未决:一种状态,描述的是信号从注册成功到处理之前的状态
信号是会打断当前阻塞操作
重入/不可重入函数:竞态条件
一个函数在多个执行流的竞争条件下运行,如果多个执行流的争抢执行不会对其他执行流造成影响,这个函数就称之为可重入函数,否则就是一个不可重入函数
如果一个函数内部涉及到参与全局数据的修改,并且这个操作是不受保护的,非原子的,那么这个函数就是一个不可重入函数;否则就是可重入函数
volatile:是一个关键字,用于修饰一个变量,保持这个变量的内存可见性,防止编译器过度优化
SIGCHLD信号:
僵尸进程是怎么产生的?
我们前面避免僵尸进程的,是创建了子进程之后就进行进程等待,一直坚持等待是因为不知道什么时候操作系统的通知才能过来,因此一直进行等待;如果知道子进程的退出通知是什么时候来的,就不需要一直进行等待;操作系统通知父进程其实就是通过SLGCHLD信号进行通知