【Linux】进程信号

一.信号

信号用于通知一个事件的发生,会打断当前操作,去处理这个事件
前提是必须能识别这个信号

生命周期:产生->注册->注销->处理
种类:非可靠信号:1-31号;可靠信号:34-64号

查看信号种类
kill -l

在这里插入图片描述
1.信号的产生:硬件产生,软件产生
硬件产生:ctrl+c/ctrl+|/ctrl+z
软件产生:

kill -signum pid//向进程发送一个signum信号
kill(int pid,int signum)

未决:信号从产生到处理之前所处的状态

2.信号的注册
非可靠信号注册:判断pcb中的pending位图中的相应信号是否已经注册(位图是否已经置1);若未注册,则位图修改为1,向sigqueue链表中添加一个信号节点;若已经注册,则不做任何操作(事件丢失)
可靠信号注册:不管信号是否已经注册,都会向链表中添加一个新的信号节点(不会丢失)

3.信号的注销
非可靠信号注销:节点只有一个,注销就是删除节点,位图置0
可靠信号注销:节点有可能有多个,注销就是删除一个节点,判断链表中是否还有相同信号的节点,若没有则位图置0,否则位图不变,依然需要标记有这个信号要处理

4.信号的处理
当进程的运行从内核态返回用户态的时候,处理信号
信号处理方式:
1)默认处理方式–既定义好的处理方式
2)忽略处理方式–处理动作中什么都没做
3)自定义处理方式–用户自己确定信号如何处理–自定义信号的处理函数替换原有的处理函数

修改信号处理方式:
sighandler_t signal(int signum,sighandler_t handler);

自定义处理方式信号的捕捉流程:
发起系统调用->
程序的运行从用户态切换到内核态->
系统调用功能完成->
do_signal返回用户态之前,判断是否有信号处理->
sigcb()->
信号自定义回调处理完毕,sigreturn返回内核态->
当没有信号待处理,sys_sigreturn返回用户态主控流程

5.信号的阻塞
阻止信号被递达–信号依然可以注册,只是暂时不处理

阻塞信号集合:标记哪些信号暂时不被处理
  int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
  how:
  SIG_BLOCK:向阻塞集合中加入set集合中的信号block=mask|set
  SIG_UNBLOCK:从阻塞集合中移除set集合中的信号block=mask&(~set)
  SIG_SETMASK:将set集合的信号设置为阻塞集合block=set
  oldset:用于保存修改前,阻塞集合中的信号

在所有信号中,9号信号SIGKILL和19号信号SIGSTOP,无法被阻塞,无法被自定义,无法被忽略

二.可重入函数与不可重入函数

函数的重入:多个执行流程同时执行进入相同的函数
可重入:多个执行流程同时执行进入相同的函数不会造成数据二义性以及代码逻辑混乱
不可重入:多个执行流程同时执行进入相同的函数,有可能造成数据二义性以及代码逻辑混乱
当用户设计或使用一个函数时在多个执行流中,需要考虑函数是否可重入情况
函数可重入和不可重入的关键点:这个函数是否对临界资源(全局数据)进行了非原子操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值