信号
信号:是一个软件中断;通知进程发生了某件事情,中断进程当前操作;让进程去处理这件事。
前提 :(必须识别这个信号)
信号种类有很多。每个都代表不同事件。
信号是有生命周期:产生-》注册-》注销-》处理 阻塞(阻止信号被处理)
操作系统中定义的信号种类:
查看信号种类: kill -l
总共62种,1-31非可靠信号 (信号有可能丢失) 34 -64:可靠信号
信号的产生:
硬件产生:ctrl +c中断信号,ctrl+ | 退出信号 ctrl+z 停止运行当前进程
软件产生:kill -signum pid 向进程发送一个signum信号
unsiged int alarm(unsigned int seconds)
经过seconds秒之后,给自己发送一个SIGALRM信号--定时器,让cpu去处理这个信号,并且退出当前进程。
core dump:保存程序的运行信息
信号在进程中的注册:在进程PCB中做标记,标记收到了哪些信号。
未决:是一种状态----信号从产生到处理之前所处的状态。、
非可靠信号注册:判断pcb中的pending位图中相应信号是否已经注册(位图是否为1);若未注册则位图修改为1,向sigqueue链表中添加一个信号节点;若已注册。则不做任何操作。
可靠信号注册:不管信号是否已经注册,都会向链表中添加一个新的信号节点。
信号在进程中的注销:
非可靠信号:节点只有一个。注销就是删除节点,位图置0;
可靠信号:节点可能有多个,注销就是删除一个节点,判断链表中是否还有相同信号的节点;若 没有则位图置0;否则位图不变依然需要标记有这个信号待处理。
信号的处理:
信号的处理并不是立即被处理,而是选择一个合适的时机去处理信号。
进程的运行从内核态返回用户态的时候;
进程如何从用户态切换到内核态:发起系统调用;程序异常,中断。
进程运行的代码若是库函数或者用户自己写的函数,就说 当前进程运行在用户态。
信号处理有多种方式:
默认处理方式----既定义好的处理方式。
忽略处理方式-处理动作中什么都没做。
自定义处理方式---用户自己定义信号该如何处理。---自定义信号的处理函数替换原有的处理函数。
信号都是在内核态返回用户态之前处理的。
信号的阻塞:阻止信号处理。
递达:信号依然可以注册,只是暂时不处理。
在pcb中还有一个集合--阻塞信号集合--标记哪些信号暂时不被处理。
在所有的信号中,9号信号SIGKILL和19号信号SIGSTOP,无法被阻塞,无法被自定义,无法被忽略。
可重入函数与不可重入函数:
函数的重入:多个执行流程同时执行进入相同的函数。
函数的可重入与不可重入:
可重入:多个执行流程同时执行进入相同的函数,不会造成数据二义性以及代码逻辑混乱。
不可重入:多个执行流程同时执行进入相同的函数,有可能造成数据的二义性以及代码的混乱。
当用户设计一个函数或使用一个函数的时候在多个执行流中,那么这时候就需要考虑函数是否可重入情况。
函数可重入与不可重入的关键点:
这个函数中是否对临界资源(全局数据)进行了非原子的操作。