(1)信号的概念
信号是进程在运行过程中,由自身产生或由进程外部发过来的消息(事件)。信号是硬件中断的软件模拟(软中断)。每个信号用一个整型常量宏表示,以SIG开头,比如SIGCHLD、SIGINT等,它们在系统头文件<signal.h>中定义,也可以通过在shell下键入kill –l查看信号列表,或者键入man 7 signal查看更详细的说明。
信号的生成来自内核,让内核生成信号的请求来自3个地方:
(1)用户:用户能够通过输入CTRL+c、Ctrl+\,或者是终端驱动程序分配给信号控制字符的其他任何键来请求内核产生信号;
(2)内核:当进程执行出错时,内核会给进程发送一个信号,例如非法段存取(内存访问违规)、浮点数溢出等;
(3)进程:一个进程可以通过系统调用kill给另一个进程发送信号,一个进程可以通过信号和另外一个进程进行通信。
进程接收到信号以后,可以有如下3种选择进行处理:
(1)接收默认处理(SIG_DFT):接收默认处理的进程通常会导致进程本身消亡。例如连接到终端的进程,用户按下CTRL+c,将导致内核向进程发送一个SIGINT的信号,进程如果不对该信号做特殊的处理,系统将采用默认的方式处理该信号,即终止进程的执行;
(2)忽略信号(SIG_IGN):进程可以通过代码,显示地忽略某个信号的处理,但是某些信号是不能被忽略的;
(3)捕捉信号并处理:进程可以事先注册信号处理函数,当接收到信号时,由信号处理函数自动捕捉并且处理信号。
有两个信号既不能被忽略也不能被捕捉,它们是SIG_KILL和SIG_STOP。即进程接收到这两个信号后,只能接受系统的默认处理,即终止线程。
(2)signal函数
signal函数用于注册一个信号捕捉函数。
- #include <signal.h>
- typedef void (*sighandler_t)(int);
- sighandler_t signal(int signum, sighandler_t handler);
signal的第1个参数signum表示要捕捉的信号,第2个参数是个函数指针,表示要对该信号进行捕捉的函数,该参数也可以是SIG_DEF(表示交由系统缺省处理,相当于白注册了)或SIG_IGN(表示忽略掉该信号而不做任何处理)。signal如果调用成功,返回以前该信号的处理函数的地址,否则返回SIG_ERR。
sighandler_t是信号捕捉函数,由signal函数注册,注册以后,在整个进程运行过程中均有效,并且对不同的信号可以注册同一个信号捕捉函数。该函数只有一个参数,表示信号值。
例:捕捉终端CTRL+c产生的SIGINT信号:
- #include <unistd.h>
- #include <stdio.h>
- #include <sys/wait.h>
- #include <sys/types.h>
- void SignHandler(int iSignNo)
- {
- printf("Capture sign no:%d\n",iSignNo);
- }
- int main()
- {
- signal(SIGINT,SignHandler);
- while(true)
- sleep(1);
- return 0;
- }
该程序运行起来以后,通过按 CTRL+c将不再终止程序的运行。应为CTRL+c产生的SIGINT信号已经由进程中注册的SignHandler函数捕捉了。该程序可以通过 Ctrl+\终止,因为组合键Ctrl+\能够产生SIGQUIT信号,而该信号的捕捉函数尚未在程序中注册。
(3)定时机制
详细参考:http://blog.csdn.net/allen_young_yang/article/details/6717755
http://blog.csdn.net/fanwenbo/article/details/2645362
如果定时时间到,那么setitimer函数就会发出SIGALRM、SIGVTALRM、SIGPROF这三种信号;然后,我们可以通过signal函数将这三种信号注册不同的函数功能,从而实现定时执行某个function.
http://my.oschina.net/zengsai/blog/11825
http://www.2cto.com/os/201207/142501.html