Linux信号机制分析

信号机制是unix采用的一种很古老的进程通信方式(linux搬过来用),用来向一个进程通知另一个进程(也可以是自己)发生了什么事,要怎样处理。

1.信号:
    信号就是在signal.h中定义的一系列以SIG开头的宏,实质是整数。信号可以通过进程(调用kill,raise,alarm,abort等,实质还是内核发信号)发出,也可以是内核(通过用户按下ctl+c)发出。信号也叫软中断。注意,信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据。  

2.信号机制: 

弄明白内核如何向一个进程发送信号、进程如何接收一个信号、进程怎样控制自己对信号的反应、内核在什么时机处理和怎样处理进程收到的信号
 1.内核通过在进程的struct task_struct中的信号域中设置相应的为其来实现向一个进程发送信号。
在进程表的表项中(struct task_struct)有一个软中断信号域,该域中每一位对应一个信号,当有信号发送给进程时,对应位置位。由此可以看出,进程对不同的信号可以同时保留,但对于同一个信号,进程并不知道在处理之前来过多少个。
 2. 进程在由内核态返回用户态时检查是否收到信号(进程处于运行running状态,会对信号进行处理。),或者是在 要进入或离开一个适当的低调度优先级睡眠状态时(看该进程进入睡眠的优先级,如果进程睡眠在可被中断的优先级上,则唤醒进程;否则仅设置进程表中信号域相应的位,而不唤醒进程,进程就不会对信号进行)。

3.信号分类:
发出信号的原因很多,这里按发出信号的原因简单分类,以了解各种信号: 
(1) 与进程终止相关的信号。当进程退出,或者子进程终止时,发出这类信号。 
(2) 与进程例外事件相关的信号。如进程越界,或企图写一个只读的内存区域(如程序正文区),或执行一个特权指令及其他各种硬件错误。 
(3) 与在系统调用期间遇到不可恢复条件相关的信号。如执行系统调用exec时,原有资源已经释放,而目前系统资源又已经耗尽。 
(4) 与执行系统调用时遇到非预测错误条件相关的信号。如执行一个并不存在的系统调用。 
(5) 在用户态下的进程发出的信号。如进程调用系统调用kill向其他进程发送信号。 
(6) 与终端交互相关的信号。如用户关闭一个终端,或按下break键等情况。 
(7) 跟踪进程执行的信号。

信号处理方法: 
收到信号的进程对各种信号有不同的处理方法。处理方法可以分为三类:第一种方法是通过定义一个函数指针(原型为 void (*)(int)作为处理函数对需要处理的信号进行处理。第二种方法是通过宏SIG_IGN(定义在signal.h中的一个函数指针)忽略某个信号,对该信号不做任何处理,就象未发生过一样。第三种方法是通过SIG_DFL(定义在signal.h中的一个函数指针)对该信号的处理保留系统的默认值,这种缺省操作,对大部分的信号的缺省操作是使得进程终止。

5  信号处理流程
对于一个完整的信号生命周期(从信号发送到相应的处理函数执行完毕)来说,可以分为三个阶段:
信号的安装
信号产生
信号的执行

5.1 信号的安装(设置信号关联动作)
如果进程要处理某一信号,那么就要在进程中安装该信号。安装信号主要用来确定信号值及进程针对该信号值的动作之间的映射关系,即进程将要处理哪个信号;该信号被传递给进程时,将执行何种操作。
linux主要有两个函数实现信号的安装:signal()、sigaction()。
其中signal()在可靠信号系统调用的基础上实现, 是库函数。它只有两个参数,不支持信号传递信息,主要是用于前32种非实时信号的安装;
而sigaction()是较新的函数(由两个系统调用实现:sys_signal以及sys_rt_sigaction),有三个参数,支持信号传递信息,主要用来与 sigqueue() 系统调用配合使用,当然,sigaction()同样支持非实时信号的安装。sigaction()优于signal()主要体现在支持信号带有参数。

5.2 信号产生
信号事件的发生有两个来源:硬件来源(比如我们按下了键盘或者其它硬件故障);软件来源,最常用发送信号的系统函数是发送信号的主要函数有:kill()、raise()、 sigqueue()、alarm()、setitimer()以及abort()。,软件来源还包括一些非法运算等操作。

你可能感兴趣的:(linux,unix,struct,kill,终端,Signal)