作者:pianpianboy
出处:翩翩男孩blog
前言:
信号这一章在《unix环境高级编程》中应该算是重点了,但是作为一个初学者,对这一章有很多疑惑。自己三遍下来对于书中很多细节还是不能心领神会,在此说说自己的想法。
一、信号定义:
信号是一种软件中断,处理异步事件的重要的方法,每种信号都是以大写的SIG开头,如SIGABRT、SIGALRM等。
二、信号的产生:
- 通过终端产生信号,如 按下相应的终端按键 ctr+c、 ctr+\等时会产生相应的中断SIGI NT、SIGQUIT信号;
- 硬件异常时产生信号,如《unix环境高级编程》181页程序的 语句 status /= 0 将产生 SIGFPE信号;或者无效的内存也会产生SIGSEGV信号;
- 进程调用kill函数,也会产生相应的信号;
三、信号的作用:
相应的事件发生,然后便产生了信号,再然后呢?谁来接受这个信号?谁来处理这个信号?信号的作用对象是谁?
产生的信号对进程而言是随机事件,进程不能简单的测试一个变量来判断是否产生了一个信号,而是必须告诉内核“在此信号出现时,该执行相应的操作”。那问题随之而及:这些操作是?
- 忽略此信号:大多数信号都可以使用这种方式进行处理,但要注意SIGKILL、SIGSTOP这二种信号是不能被忽略的(因为它们向超级用户提供了使进程终止或停止的可靠方法);
- 捕捉此信号:这是信号处理最重要的方法,也是信号的难点。这时就要用到了信号函数void (*signal( int signo,void(*func)(int)))(int),为了做到这一点,要通知内核在某种信号发生时调用一个用户函数(也就是信号函数中的func),在用户函数中,可执行用户希望对这件事件的处理。比如捕捉到了SIGCHILD信号,则表示一个进程已终止,则可以通过此信号的捕捉函数调用waitpid()函数获取子进程的终止状态;
- 按默认处理此信号:针对大多数系统默认是终止进程;
四、signal 函数:
unix 系统信号机制最简单的接口是signal 函数。
#include <signal.h>
void (* signal(int signo, void (*func)(int))) (int)
其中参数 :信号signo 、函数指针func。
signo参数表示信号名,如SIGALRM、SIGINT、SIGQUIT等
func参数 表示函数指针,func的值是常量SIG_IGN(1.忽略此信号)常量SIG_DFL(3.默认处理此信号)或当接到此信号后要调用的函数的地址。指定当捕捉到相应的信号时,内核必须执行的的操作(如上提到的1.忽略此信号 2.捕捉此信号 3.默认处理此信号)。
当指定函数地址时,当信号发生时,调用该函数,我们称这种处理为“捕捉”该信号,称此函数为信号处理程序或信号捕捉函数。