接着我们之前的管道所提出来的问题()
在创建子进程之后,子进程究竟何时终止????调用waitpid函数后还要无休止的等待子进程终止吗???”,这显然会是一个问题。因为父进程往往与子进程一样繁忙,因此我们不能只调用waitpid函数来等待子进程终止。那么我们应该怎么办呢???
信号闪亮登场!!!!!
由于本对信号的描述太少,博主在这里就多给大家普及一下,希望大家对信号有更加深刻而性感的认识(因为信号与进程守护也有关系)。子进程终止的识别主体是操作系统,如果,操作系统能把如下信息告诉正在忙于工作的父进程,那么将会有助与构建高效的程序。
嘿! 父进程! 你创建的子进程终止了哟。快去回收
此时父进程将暂时放下工作,处理子进程种植的相关事宜,这样的想法是不是非常的炫酷呢??事实上我们利用信号就能做到这一点,那么我们就开始对信号的介绍吧。
信号的概念:
信号在我们的生活中随处可见, 如:古代战争中烽火传信;体育比赛中使用的信号枪......他们都有共性:1. 简单 2. 不能携带大量信息 3. 满足某个特设条件才发送。(这也就是我们linux下的信号的概念)
信号的机制:
A给B发送信号,B收到信号之前执行自己的代码,收到信号后,不管执行到程序的什么位置,都要 暂停运行,去处理信号,处理完毕再继续执行。与硬件中断类似——异步模式。但信号是软件层面上实现的中断,早期常被称为“软中断”。
信号的特质:由于信号是通过软件方法实现,其实现手段导致信号有很强的延时性。但对于用户来说,这个延迟时间非常短,不易察觉。 每个进程收到的所有信号,都是由内核负责发送的,内核处理。
所以说上才会有信号与signal函数: ![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20191031211217894.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RlYXJRaUhhbw==,size_16,color_FFFFFF,t_70)
下面是博主摘抄的写的比较好的有关信号的描述:
产生信号的方式: 1. 按键产生,如:Ctrl+c、Ctrl+z、Ctrl+\
2. 系统调用产生,如:kill、raise、abort
3. 软件条件产生,如:定时器alarm
4. 硬件异常产生,如:非法访问内存(段错误)、除0(浮点数例外)、内存对齐出错(总线错误)
5. 命令产生,如:kill命令
递达:递送并且到达进程。
未决:产生和递达之间的状态。主要由于阻塞(屏蔽)导致该状态。 信号的处理方式:
6. 执行默认动作
7. 忽略(丢弃)
8. 捕捉(调用户处理函数)
Linux内核的进程控制块PCB是一个结构体,task_struct, 除了包含进程id,状态,工作目录,用户id,组id,文件描述符表,还包含了信号相关的信息,主要指阻塞信号集和未决信号集。
. 阻塞信号集(信号屏蔽字): 将某些信号加入集合,对他们设置屏蔽,当屏蔽x信号后,再收到该信号,该信号的处理将推后(解除屏蔽后) 未决信号集:
9. 信号产生,未决信号集中描述该信号的位立刻翻转为1,表信号处于未决状态。当信号被处理对应位翻转回为0。这一时刻往往非常短暂。
10. 信号产生后由于某些原因(主要是阻塞)不能抵达。这类信号的集合称之为未决信号集。在屏蔽解除前,信号一直处于未决状态。
上面的大家可以多了解下,我们要讲的就是第八个 捕捉,也就是注册一个信号捕捉函数,当接到信号后就去回调要做的处理。也就是图片上所说的![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20191031211953582.png) 好了,那现在我们就来了解下一我们的信号捕捉吧。
signal() 与 sigaction()
signal()函数
#include<signal.h> void (*signal)(int signo, void(*func)(int)))(int); 这个就比较复杂了,上述函数的返回值类型为函数指针,而且涉及到了回调函数,要在这里讲清楚会浪费大量篇幅, 所以博主打算在明天博主放假了再做详细讲解。敬请期待
虽然这篇博客就要结束了,但是这篇博客你好好看下来一定会有所收获。
最后的黑科技
最后的图片很熟悉吧,哈哈,这其实就是信号的机制。
谢谢观看,明天就开始函数指针和回调函数,然后就让我们来征服信号捕捉器吧!!!!