Linux下信号的总结与概况

信号:是一个软件中断;通知进程发生了某件事情,会打断当前进程的操作;让进程去处理这些事件
1.信号的分类:有很很多中 62种 分为两大类 :可靠信号34~64/非可靠信号 1到31 (中间有两个没有 32 33) 进程必须识别这些信号(不识别就没有信号的意义)
1)1到31是基于liunx操作系统而来 (有可能丢失事件)
2) 34到64 因为信号不够用 但没有特定的命名(可靠信号或者实时信号 ,不会丢失事件)
3) 常见信号 SIGSEGV 段错误 内存访问越界
SIGFPE 除法时分母为0
SIGKILL 杀死进程信号
2.相关命令:查看信号种类-kill-l kill杀死进程原理:向进程发送信号-通知事件
3.信号生命周期:信号的产生->在进程中注册->在进程中注销->信号处理 (信号发生后会向在该进程的pcb中注册 再该进程得到时间片的时候,先在进程中注销该信号,然后再执行; 信号可以阻塞(有两个信号不能阻塞 因为如所有信号都被阻塞 则程序可能会一直运行);
4.信号的产生:
1)硬件产生:例如 ctrl+c(中断信号) ctrl+|(退出信号) ctrl+z停止信号
2)软件产生:kill - signum pid(向指定进程发生指定信息,啥信号都行只要能识别,包括在一个程序在根本不存在段错位的情况下使用 发送 SIGSEGV信号,在进程收到后直退出 并报错发生段错位)一下常用接口
1) 函数 int kill(pid,signum)pid 为进程名称 signum为信号的序号 可以给自己发getpid()这个函数可以获取自己的pid 可以实现自杀。 也可以给别人发。 如果进程不存在返回-1;
2)函数 int raise(signum)给自己发送相关信号
3)函数 void abort(void);自己给自己发送终止信号
4)函数 unsigned int alarm(nsec)定时器 时间到默认是进程终止,nesec为时间 定时器运行的只能有一个 如果设置了多个,上一个定时器还没退出则还没退出的情况下遇到下一个时间会变成下一个的时间 如果一个定时器时间没到 alarm (0);则取消上一个定时器;

5. 信号在进程中的注册:在pcb中使用位图(sigset_t 标记用)/可靠性信号(sigqueue 添加节点)标记进程是否收到信号 ,PCB 的pending结构体中的一个位置进行标记表示信号已经到来
1)非可靠信号 :信号到来后先看pending结构体标记的位置是否为0;如果为零则将其改变为1 1.值后再在sigqueuq这个链表中添加信号节点,如果为0(已经注册)则不执行任何操作,该信号被忽视。
2)可靠信号:前面相同 ,后面不管信号是否已经注册,会一直把新信号的节点添加进去,不会丢失信号。
3)信号注册后,如果没有检测信号是否到来,则称未决状态
4)两种信号之分,是否针对以及注册的信号添加新的信号节点

6.信号的注销:在PCB中抹除信号存在的痕迹(修改位图,删除节点)
1)非可靠信号:节点只有一个,删除该节点,位图置零
2)可靠性和:节点可能有多个,注销就是删除一个节点,然后再判断是否还有节点,如果没有位图置为0;如果有则继续上述操作 (位图表示还有没有信号)
7.信号的处理
信号的处理并不是立即被处理;而是选择一个合适的时机;
当程序从内核态返回用户态的时候处理;
(内核态:系统调用,操作系统提供的接口;用户态:自己编的代码)
1)进程如何从用户态切换为内核态:发起系统调用;程序异常;中断
进程运行的代码若是库函数或者自己写的函数,就说进程当前运行再用户态;
2)信号处理方式:1.默认处理方式 : 既定义好的处理方式 2. 忽略处理方式 处理动作中什么都没有做 3.自定义处理方式 用户自己确定信号如何处理 自定义信号的处理函数替换原有的处理函数
4.处理过程
自定义处理方式信号的捕捉流程
*

当系统掉用完成后需要从用内核态转回到用户态,调用do_signal看是否有信号待处理,如果没有直接退出,如果有自定义信号,则进入用户态进行执行信号函数,当函数执行完后 sig_retuen返回内核态,再检测还有没有待处理信号,如果有继续上述过程,如果没有则直接退出;(可参照上图)
3)如何修改信号处理方式: sighandler_t signal(int signum, sighandler_t handler);
① int signum为要修改的信号ID
②sighandler_t handler:函数指针,新的函数,SIG_DFL:信号的默认处理动作,SIG_IGN:忽略信号;
4)int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);用2替换1,2再放到3中
**
9.信号的阻塞:阻止信号被递达 递达:一个动作–信号的处理(信号依然可以注册只是暂时不处理)
再pcb中还有一个集合–阻塞信号集合–标记那些信号不被处理
原理:在这里插入图片描述
如图:信号再pending中注册当要执行信号的时候现在block匹配,如果对应的信号被阻塞则不会执行。
函数: int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
how(有三个参数):SIG_BLOCK 向阻塞集合中加入set集合中的信号 block = make | set
SLG_UNBLOCK 从阻塞集合中移除set集合中的信号 block = make&(~set)
SLG_SETMASK 将set集合中的信号设置为阻塞集合 block = set
oldest 用于保存替换前的信号
10不可被阻塞信号
9号信号SIGKILL和19号信号SIGSTOP不可以被阻塞,被自定义等操作,防止所有信号被阻塞,使得该程序退出。

11:可重入函数与不可重入函数
函数的重入:多个执行流程同时执行进入相同的函数,例如一个进程调用一个函数A 此时信号输入 ,而对信号处理的过程中 信号也调用了函数A ;此时就发生了函数的重入;
函数的可重入与不可重入:
可重入:多个执行流程同时执行相同的函数,不会造成数据的二义性以及代码的逻辑混乱
不可重入:多个执行流程同时执行进入相同的函数,有可能造成数据二义性以及代码的逻辑混乱
函数是否可重入: 函数是否对临界资源(全局数据)进行了非原子操作(不受保护的操作);
关键点:在一个函数中是否对临界资源进行了不受保护的非原子操作

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值