目录
进程信号,在我还未理解前,根本无法理解一个进程是任何可以收到信号的,是以什么方式收到信号的。
理解进程信号
首先理解信号,通俗的来说信号类似一种通知,当你收到通知你知道应该下一步的动作。
绿灯亮了,过马路。上课铃响了,进教室。而在我们的进程和人一样,时刻准备着接收信号。
那么进程如何接收信号呢?接收信号又该如何做呢?
我们看看有哪些信号:
我们将信号分为:普通信号(1~31)以及实时信号(34~64),我们日程编程中更重于关注普通信号,在进程收到信号的时候并不是一定是立刻处理该信号,而是在合适的时候再去处理。
比如:打王者在推高地,但是突然妈妈叫你吃饭了,你会立刻处理放下手机去吃饭吗?所以我们需要将接收到的信号先保存起来,在合适的时候处理。普通的信号可以这样做,但是如果是特殊场景:你妈妈拿着棍子叫你吃饭,你就要立刻放下手机,处理妈妈给你发的信号。这就需要实时信号。
进程保存信号以及方法
我们这里不讨论实时信号先,这里我们先抛出俩个疑问:
1:我们怎么知道什么信号来了?某个信号来了,我们应该对应做什么呢?红灯停绿灯行这个信号是教育日积月累学习的,上课铃响了我们要就去教室。这里没有看见红绿灯我们也知道这个方法,没有听到上课铃我们也知道响了进教室。这都是别人告诉我的,
2:当前没空,能不能等等在做,将信号先保存起来。但是怎么保存呢?
3:怎么甄别信号等待
三个问题解决:
接收信号保存(pending表
先说第二个问题,我们发现普通信号只有32个,我们只是需要知道这32个信号某个信号是否来临。所以linux采用了位图的方式保存32个信号是否来了的检查机制。我们用4个字节就可以保存32个信号是否来临
用一个int就可以保存32个信号是否方式。位图真nb
那么这些比特位的反转谁来完成的呢?
来来来:一个共识先:只有OS才有权力给进程发(写)信号!!!
那么收到信号之后的处理存放在哪里呢?
信号是否阻塞(block表
也是类似pending表一样使用一个位图,保存对应pending表中信号产生后是否需要阻塞。
被阻塞的信号在解除阻塞后会被执行。当进程调用系统函数或其变体之一来阻塞信号时,被阻塞的信号将被添加到进程的信号屏蔽字中。进程的信号屏蔽字指定了哪些信号当前被阻塞,无法被递送给进程。当解除对某个信号的阻塞后,如果该信号此时已经到达,则会立即执行信号处理函数。如果该信号在阻塞期间被重复递送多次,那么只有在解除阻塞时最后一次递送的信号会被执行。需要注意的是,如果某个信号一直处于阻塞状态,那么它将不会被执行,直到解除对该信号的阻塞。因此,如果某个信号被阻塞了很长时间,而在解除阻塞之前已经递送了多次该信号,那么只有最后一次递送的信号会在解除阻塞后被执行。
信号动作保存(hardler表
在Linux中,信号处理方法是保存在一个称为信号处理函数表(Signal Handler Table)的数据结构中。该数据结构是一个数组,每个数组元素对应一个信号的处理方法。数组的索引即为信号的编号,因此可以通过信号编号来访问对应的信号处理方法。当接收到一个信号时,os内核会根据信号编号在信号处理函数表中查找对应的处理方法,并执行该方法来响应信号。
在大多数 Linux 系统中,Signal Handler Table 的大小是固定的,通常为 32 或 64 个元素。这意味着最多可以为 32 或 64 种不同的信号注册处理函数。每个元素对应一个信号的处理函数,可以通过信号的编号来索引到对应的元素。当然,这个数量可能因操作系统版本、内核配置或特定的系统限制而有所不同。
信号的3个状态:
1、信号递达(Delivery):信号递达指的是进程实际执行信号的处理动作。
2、信号未决(pending):信号从产生到递达之间的状态。
3、阻塞(block):进程可以选择阻塞一个信号。被阻塞的信号产生时将保持在未决状态,直到进程解除对该信号的阻塞,才能执行递达的动作。
信号产生和阻塞没有直接关系,信号递达和解除阻塞没有直接关系!
我们以32个信号画图
注意当信号处理后,我们会改变比特位。
今天的重点不是这个,我以后再写一篇关于三表的文章(其实现在知识水平不太够)
信号功能解释
让我们输入一份指令,打开信号手册