【Linux】信号的捕捉(捕捉过程及捕捉函数)

信号的捕捉过程

我们现在知道了信号在产生之后不是被立即处理的,而是在合适的时候才进行处理,那么什么时候是合适的时候呢?信号又是怎么被捕捉的呢?

合适的时候是指:从内核态切换为用户态时进行信号的捕捉。

在Linux下,作为普通用户的我们会发现我们有时候会有一些文件不能进入、有一些文件不能创建、有一些信息不能看、我们创建的进程总数总是有上限的,我们访问不了硬件层面的 东西,感觉自己被限制了,其实这就是一种权限。

内核态和用户态都是一种状态,这两种状态表示了两种身份,这两种身份表示了不同的权限等级,我们在访问0-3G的地址空间时,我们用的是用户权限,而我们通过系统调用接口以及我们想要访问地址空间里的3-4G空间时,我们就需要把自己的身份从内核态转换为用户态。因此,内核态和用户态最大的区别就是权限,内核态允许访问3-4G的空间

【Linux】信号的捕捉(捕捉过程及捕捉函数)

从用户态到内核态的过程是权限升级的过程,而从内核态到用户态的过程是要从安全方面考虑的,因为操作系统不相信任何人,只相信它自己,所以要想要访问操作系统内部进行访问时必须通过系统调用接口。操作系统的代码只能由操作系统执行,用户的代码就只能由用户执行,因此就会有内核态和用户态两种状态之间的相互转变。

如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号。由于信号处理函数的代码
是在用户空间的,处理过程比较复杂,举例如下: 用户程序注册了SIGQUIT信号的处理函数sighandler。 当前正在执行
main函数,这时发生中断或异常切换到内核态。 在中断处理完毕后要返回用户态的main函数之前检查到有信号
SIGQUIT递达。 内核决定返回用户态后不是恢复main函数的上下文继续执行,而是执行sighandler函 数,sighandler
和main函数使用不同的堆栈空间,它们之间不存在调用和被调用的关系,是 两个独立的控制流程。 sighandler函数返
回后自动执行特殊的系统调用sigreturn再次进入内核态。 如果没有新的信号要递达,这次再返回用户态就是恢复
main函数的上下文继续执行了。如下图:

【Linux】信号的捕捉(捕捉过程及捕捉函数)

信号捕捉函数

1.signal

#include <signal.h>
sighandler_t signal(int signum, sighandler_t handler);

捕捉2号信号 

【Linux】信号的捕捉(捕捉过程及捕捉函数)

2.sigaction

#include <signal.h>
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);

捕捉2号信号 

【Linux】信号的捕捉(捕捉过程及捕捉函数)