信号是UNIX中所使用的进程通信的一种最古老的方法,是一种异步通信方式。信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。它可以在任何时候发给某一进程,而无需知道该进程的状态。
一个完整的信号生命周期可以分为如下阶段
用户进程对信号的响应可以有3种方式。
忽略信号,即对信号不做任何处理,但是有两个信号不能忽略,即SIGKILL及SIGSTOP。
捕捉信号,定义信号处理函数,当信号发生时,执行相应的自定义处理函数。
执行缺省操作,Linux对每种信号都规定了默认操作,比如linux终端经常用ctrl+c终止某个进程
信号发送
kill()
kill()函数可以发送各种信号给进程或进程组,成功返回0
raise()
与kill()函数所不同的是,raise()函数允许进程向自身发送信号。
alarm()
alarm()也称为闹钟函数,它可以在进程中设置一个定时器,当定时器指定的时间到时,它就向进程发送SIGALARM信号。要注意的是,一个进程只能有一个闹钟时间,如果在调用alarm()之前已设置过闹钟时间,则任何以前的闹钟时间都被新值所代替。
pause()
pause()函数是用于将调用进程挂起直至捕捉到信号为止。这个函数很常用,通常可以用于判断信号是否已到。
注意:程序中有多少个pause(),就对应捕捉多少个信号
信号捕捉
信号处理的主要方法有两种,一种是使用简单的signal()函数,另一种是使用信号集函数组。 使用信号集函数组处理信号时涉及一系列的函数来创建信号集、注册信号处理函数及检测信号等,信号集函数组使用较少,就不研究了。
最后一个简单的例子
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
void alarm_handler(int signum)
{
printf("I have been waken up by signal(%d).\n",signum);
}
int main()
{
int ret;
signal(SIGALRM,alarm_handler);
ret=alarm(3);
pause();
printf("The alarm return value is (%d).\n",ret);
return 0;
}