信号是一种机制,是在软件层次对中断机制的一种模拟,内核让某进程意识到某特殊事情发生了。强迫进程去执行相应的信号处理函数。至于信号的来源可能来自硬件如按下键盘或者硬件故障(如ctrl+c发送SIGINT),可能来自其他进程(kill,sigqueue),可能来自自己进程(raise)。
信号的产生:
1,当用户按下某些按键时,产生信号.
2,硬件异常产生信号:除数为 0 ,无效的存储访问等等.这些情况通常由硬件检测到,将其通知内核,然后内核产生适当的信号通知进程,例如,内核对正访问一个无效存储区的进程产生一个 SIGSEGV 信号.
3,进程用 kill 函数 将信号发送给另一个进程.
4,用户可用 kill 命令将信号发送给其他进程.
信号类型
信号的名字是由所包含的头文件signal.h来定义的。他们以"SIG"开头,如下所示:
信号名 描述
SIGABORT 处理失败
SIGALRM 报警时钟
SIGFPE 浮点异常
SIGHUP 挂起
SIGILL 非法指令
SIGKILL Kill(不能被捕获或是忽略)
SIGPIPE 写入没有读端的管道
SIGQUIT 终端退出(ctrl+/)
SIGSEGV 非法的内存段访问
SIGTERM 终止
SIGUSR1 用户定义的信号1
SIGUSR2 用户定义的信号2
SIGHUP :从终端上发出的结束信号.
SIGINT :来自键盘的中断信号 ( ctrl + c ) .
SIGTERM:kill 命令发出 的信号.
SIGCHLD:标识子进程停止或结束的信号.
SIGSTOP:来自键盘 ( ctrl + z ) 或调试程序的停止执行信号.
信号处理
当某信号出现时,将按照下列三种方式中的一种进行处理.
1,忽略此信号:大多数信号都按照这种方式进行处理,但有两种信号却决不能被忽略.它们是:SIGKILL 和 SIGSTOP . 这两 种信号不能被忽略的原因是:它们向超级用户提供了一种终止或停止进程的方法.
2,执行用户希望的动作:通知内核在某种信号发生时,调用一个用户函数,在用户函数中,执行用户希望的处理.
3,执行系统默认动作:对大多数信号的系统默认动作是终止该进程.
当系统捕捉到某个信号时,可以忽略该信号或是使用指定的处理函数来处理该信号,或者使用系统默认的方式。
信号处理的主要方法有两种,一种是使用简单的 signal 函数,另一个是使用信号集函数.
signo--信号名字
例如:typedef void (*handler)(int)
pause 函数
#include <signal.h>
int pause ( void ):
pause 函数使调用进程挂起直至捕捉到一个信号。例子1:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void ouch(int sig)
{
printf("I got signal %d\n", sig);
(void) signal(SIGINT, SIG_DFL);
//(void) signal(SIGINT, ouch);
}
int main()
{
(void) signal(SIGINT, ouch);
while(1)
{
printf("hello world...\n");
sleep(1);
}
}
解析:
例子2:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void my_func(int sign_no)
{
if(sign_no==SIGINT)
printf("I have get SIGINT\n");
else if(sign_no==SIGQUIT)
printf("I have get SIGQUIT\n");
}
int main()
{
printf("Waiting for signal SIGINT or SIGQUIT \n ");
/*注册信号处理函数*/
signal(SIGINT, my_func);
signal(SIGQUIT, my_func);
pause();
exit(0);
}
解析:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void sig_usr(int sig);
int main(int argc,char *argv[])
{
int i = 0;
if(signal(SIGUSR1,sig_usr) == SIG_ERR)
printf("Cannot catch SIGUSR1\n");
if (signal(SIGUSR2,sig_usr) == SIG_ERR)
printf("Cannot catch SIGUSR2\n");
while(1) {
printf("%2d\n", i);
pause();
/* pause until signal handler
has processed signal */
i++;
}
return 0;
}
void sig_usr(int sig)
{
if (sig == SIGUSR1)
printf("Received SIGUSR1\n");
else if (sig == SIGUSR2)
printf("Received SIGUSR2\n");
else
printf("Undeclared signal %d\n", sig);
}