#include <stdio.h>
#include <signal.h>

void handler(int signo);

int main(int argc, char ** argv)
{
sigset( SIGINT , handler );
sigset( SIGQUIT , handler );
sigset( SIGKILL , handler );
sigset( SIGTERM , handler );
signal( SIGALRM , handler );
signal( SIGUSR1 , handler );
signal( SIGUSR2 , handler );
alarm(3);//3s后发送SIGALARM信号给自己

printf( "Process_pid=[%d]\n", getpid() );
while(1){
int ch = getchar();
if('z' == ch){
kill(getpid(),SIGINT);
}else if('x' == ch){
kill(getpid(),SIGQUIT);
}else if('c' == ch){
kill(getpid(),SIGKILL);//按下c程序退出,因为此信号不可忽略
}else if('v' == ch){
raise(SIGTERM); //or kill(getpid(),SIGTERM);
}else if('b' == ch){
raise(SIGUSR1);
}else if('n' == ch){
raise(SIGUSR2);
}else if('m' == ch){
raise(SIGALRM);
}
}
return 0;
}

void handler(int signo)
{
switch(signo) {
case SIGINT: //处理信号 SIGINT
printf("SIGINT received...\n");
break;
case SIGQUIT: //处理信号 SIGINT
printf("SIGINT received...\n");
break;
case SIGKILL: //处理信号 SIGKILL
printf("SIGKILL received...\n");//永远不会到此
break;
case SIGTERM: //处理信号 SIGTERM
printf("SIGTERM received...\n");
break;
case SIGUSR1: //处理信号 SIGUSR1
signal(SIGUSR1,SIG_IGN); //第一次输出,第二次以后因为忽略了信号,所以没有输出了
printf("SIGUSR1 received...\n");
break;
case SIGUSR2: //处理信号 SIGUSR2
printf("SIGUSR2 received...\n");//第一次输出,第二次因为设置了默认处理方式(退出),所以程序就退出了
signal(SIGUSR2,SIG_DFL);
break;
case SIGALRM: //处理信号 SIGALRM
printf("SIGALRM received...\n");
break;
default:
fprintf(stderr,"Should not be here...\n");
break;
}
}

signal() 与sigset() 的同异
在有些版本的UNIX系统中,signal() 会在调用信号处理函数前,重设该信号的动作为系统缺省动作。如果应用程序希望在响应信号后仍然按照自己的动作处理该信号,则必须在信号处理函数的第一行中使用signal()重设该动作。
sigset()解决了signal()存在的上述问题。其余功能和特性与signal()相同。
所以尽量用sigset()。