加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

Linux内核信号处理机制详解

发布时间:2021-11-24 17:30:15 所属栏目:PHP教程 来源:互联网
导读:本文简单介绍下Linux信号处理机制,为介绍二进制翻译下信号处理机制做一个铺垫。 本文主要参考书目《Linux内核源代码情景分析》《独辟蹊径品内核:Linux内核源代码导读》 首先,先说一下什么是信号。信号本质上是在软件层次上对中断机制的一种模拟,其主要有

本文简单介绍下Linux信号处理机制,为介绍二进制翻译下信号处理机制做一个铺垫。
本文主要参考书目《Linux内核源代码情景分析》《独辟蹊径品内核:Linux内核源代码导读》
 
首先,先说一下什么是信号。信号本质上是在软件层次上对中断机制的一种模拟,其主要有以下几种来源:
 
程序错误:除零,非法内存访问…
外部信号:终端Ctrl-C产生SGINT信号,定时器到期产生SIGALRM…
显式请求:kill函数允许进程发送任何信号给其他进程或进程组。
在Linux下,可以通过以下命令查看系统所有的信号:
 
kill -l
可以通过类似下面的命令显式的给一个进程发送一个信号:
 
kill -2 pid
上面的命令将2号信号发送给进程id为pid的进程。不存在编号为0的信号。
 
目前Linux支持64种信号。信号分为非实时信号(不可靠信号)和实时信号(可靠信号)两种类型,对应于 Linux 的信号值为 1-31 和 34-64。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。本文着重于Linux的信号处理机制。
 
一般情况下一个进程接受到信号后,会有如下的行为:
 
进程对信号的响应
 
忽略信号:大部分信号可被忽略,除SIGSTOP和SIGKILL信号外(这是超级用户杀掉或停掉任意进程的手段)。
捕获信号:注册信号处理函数,它对产生的特定信号做处理。
让信号默认动作起作用:unix内核定义的默认动作,有5种情况:
a) 流产abort:终止进程并产生core文件。
b) 终止stop:终止进程但不生成core文件。
c) 忽略:忽略信号。
d) 挂起suspend:挂起进程。
e) 继续continue:若进程是挂起的,则resume进程,否则忽略此信号。
注册信号处理函数
 
如果想要进程捕获某个信号,然后作出相应的处理,就需要注册信号处理函数。同中断类似,内核也为每个进程准备了一个信号向量表,信号向量表中记录着每个信号所对应的处理机制,默认情况下是调用默认处理机制。当进程为某个信号注册了信号处理程序后,发生该信号时,内核就会调用注册的函数。
 
注册信号处理函数是通过系统调用signal()、sigaction()。其中signal()在可靠信号系统调用的基础上实现, 是库函数。它只有两个参数,不支持信号传递信息,主要是用于前32种非实时信号的安装;而sigaction()是较新的函数(由两个系统调用实 现:sys_signal以及sys_rt_sigaction),有三个参数,支持信号传递信息,主要用来与 sigqueue() 系统调用配合使用,当然,sigaction()同样支持非实时信号的安装。sigaction()优于signal()主要体现在支持信号带有参数。关于这方面的内容,如果想获取更多,也可参考这里。
 
Linux下信号处理机制
进程如何发现和接受信号?
 
我们知道,信号是异步的,一个进程不可能等待信号的到来,也不知道信号会到来,那么,进程是如何发现和接受信号呢?实际上,信号的接收不是由用户进程来完成的,而是由内核代理。当一个进程P2向另一个进程P1发送信号后,内核接受到信号,并将其放在P1的信号队列当中。当P1再次陷入内核态时,会检查信号队列,并根据相应的信号调取相应的信号处理函数。如下图所示:
 
 
其中,动作c:发现和捕捉信号
 
信号检测和响应时机
 
刚才我们说,当P1再次陷入内核时,会检查信号队列。那么,P1什么时候会再次陷入内核呢?陷入内核后在什么时机会检测信号队列呢?
 
当前进程由于系统调用、中断或异常而进入系统空间以后,从系统空间返回到用户空间的前夕。
当前进程在内核中进入睡眠以后刚被唤醒的时候(必定是在系统调用中),或者由于不可忽略信号的存在而提前返回到用户空间。
进入信号处理函数
 
发现信号后,根据信号向量,知道了处理函数,那么该如何进入信号处理程序,又该如何返回呢?
 
我们知道,用户进程提供的信号处理函数是在用户态里的,而我们发现信号,找到信号处理函数的时刻处于内核态中,所以我们需要从内核态跑到用户态去执行信号处理程序,执行完毕后还要返回内核态。这个过程如下图所示:
 
 
 
如图中所见,处理信号的整个过程是这样的:进程由于  系统调用或者中断  进入内核,完成相应任务返回用户空间的前夕,检查信号队列,如果有信号,则根据信号向量表找到信号处理函数,设置好“frame”后,跳到用户态执行信号处理函数。信号处理函数执行完毕后,返回内核态,设置“frame”,再返回到用户态继续执行程序。
 
在上面这段话中,我提到“frame”,frame是什么?那么为什么要设置frame?为什么在执行完信号处理函数后还要返回内核态呢?

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读