一、什么是信号
1、 信号就是软件中断,很多的程序都需要处理信号。信号提供了一种处理异步事件的机制。
例如:当用户在终端下运行一个程序时,用户在键盘键入一个中断键(CTRL+C),则会通过信号机制终止一个正在运行的程序。
2、每一个信号都有自己独特的名字。这些名字都是以SIG开头的。例如中断信号SIGINT.在linux下输入shell命令kill -l可以看到linux所支持的所有的信号名称以及信号的编号。其中1号到32号(32号信号用户是不能使用的)信号都是继承UNUX系统的信号。其余的 是linux系统根据POSIX标注定义的信号。
3、在编写信号程序时,必须加上头文件。事实上,信号的定义的定义在另外的一个头文件中,但是该头文件又包含在中。
大家可以查看头文件/usr/include/signal.h 发现里边有一句include ,然后再查看头文件/usr/include/bits/signum.h 大家会发现信号的定义都在这里边.
二、信号产生的方式
1、用户按键,如用户按下了CTRL+C组合键
2、硬件异常,如除数为0,无效内存引用
3、进程调用kill函数将信号发送给一个进程或者进程组,限制条件是:接受信号进程和发送信号进程的所有者必须相同。或者发送信号的进程的所有者是超级用户
4、调用命令kill,实际上此命令是kill函数的接口
5、检测到某种软件条件已经发生。例如 SIGPIPE(管道的读进程已经终止后,另一个进程写此管道时产生)
当产生信号时,内核通常会在进程表中设置一个某种形式的标志,这就是所谓的向进程发送了一个信号。
三、进程的处理
1、捕捉信号,可以指定信号的处理函数,当捕捉的信号时自动执行此函数
2、忽略信号,除了SIGKILL和SIGSTOP,因为它们向超级用户提供了使进程终止或停止的方法。另外忽略了由某些硬件异常产生的信号(如无效内存引用),则进程运行的行为是不可预测的。
3、按照系统默认的方式处理,大部分信号的默认处理方式是终止进程
四.linux下的信号
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
五.简单实例
1.单信号处理
#include"stdio.h"
#include"signal.h"
void SignalHandler(int iSignNum)
{
printf("capture signal number:%d\n",iSignNum);
}
int main()
{ // 程序运行Ctrl+c将不能终止,因为“Ctrl+c”产生的信号SIGINT
//将交给已经注册的自定义函数处理,“Ctrl+\”终止是因为它产生的SIGQUIT尚未在程序中注册
signal(SIGINT,SignalHandler);
while(1)
sleep(1);
return 0;
}
2.多信号处理
#include"stdio.h"
#include"signal.h"
#include"sys/types.h"
#include"unistd.h"
void SigRoutine(int iSignNum)
{
switch(iSignNum)
{
case 1:
printf("capture SIGHUP signal, signal number is %d\n",iSignNum);
break;
case 2:
printf("capture SIGINT signal, signal number is %d\n",iSignNum);
break;
case 3:
printf("capture SIGINT signal, signal number is %d\n",iSignNum);
break;
}
}
int main()
{
printf("process ID is %d\n",getpid());
if(signal(SIGHUP,SigRoutine) == SIG_ERR)
{
printf("coundn't register signal handler for SIGHUP");
}
if(signal(SIGINT,SigRoutine) == SIG_ERR)
{
printf("coundn't register signal handler for SIGINT");
}
if(signal(SIGQUIT,SigRoutine) == SIG_ERR)
{
printf("coundn't register signal handler for SIGQUIT");
}
while(1)
sleep(1);
return 0;
}
3.alarm
#include"stdio.h"
#include"signal.h"
#include"sys/types.h"
#include"unistd.h"
void Handler()
{
printf("signal handler ..\n");
}
int main()
{
int i;
signal(SIGALRM,Handler);
// alarm专门为SIGALRM信号而设,使系统在一定时间后发送信号
alarm(5);
for(i=1;i<=10;i++)
{
sleep(1);
printf("sleep %ds\n",i);
}
return 0;
}
4.pause
#include"stdio.h"
#include"signal.h"
#include"sys/types.h"
#include"unistd.h"
void SigHandler(int iSignNum)
{
printf("signal:%d\n",iSignNum);
}
int main()
{
signal(SIGALRM,SigHandler);
alarm(5);
printf("before pause \n");
pause();
printf("after pause \n");
return 0;
}
转载自:http://my.oschina.net/sharelinux/blog/112791
阅读(1212) | 评论(0) | 转发(0) |