10.2安装信号与捕获信号
10.2.1信号处理办法
当进程收到操作系统一个信号,可以采用下面处理方法:
1.忽略此信号。大多数信号都可以用这种方式处理,但SIGKILL和SIGSTOP不能被忽略。
2.自定义捕捉信号方式。当某信号到来时,执行用户自定义操作,这要求该进程先安装该信号,即通知内核在某种信号发生时调用一个特殊函数。
3.执行系统默认操作。Linux对任何一个信号都规定了一个默认操作。
10.2.2signal安装信号
程序要求接收到某信号时执行用户的特殊操作,需要安装信号处理函数。
typedef void (*__sighandler_t) (int)
extern __sighander_t signal(int __sig, __sighander_t __hander);
此函数有两个参数,第一个参数sig为接收到的信号,第二个参数为接收到的此信号后处理代码入口或下面几个宏。
#define SIG_ERR ((__sighander_t) -1) //返回错误
#define SIG_DFL ((__sighander_t) 0) //执行信号的默认操作
#define SIG_IGN ((__sighander_t) 1) //忽略信号
如果执行成功,则返回针对此信号的上一次设置。
当进程接收到该信号后,将执行hander函数,在某些unix版本中,在执行完一次信号处理后有可能需要再次执行此信号的安装。因此建议在hander函数中再次安装hander信号处理函数。
当然,在目前的Linux系统中可以不这样操作。程序实例
➜ _10_SIGNALS cat kill_exp.c
#include "stdio.h"
#include "stdlib.h"
#include "signal.h"
#include "unistd.h"
void sig_usr(int sig);
int main()
{
int i = 0;
if(signal(SIGUSR1, sig_usr) == SIG_ERR)
printf("cant catch SIGUSR1\n");
if(signal(SIGUSR2, sig_usr) == SIG_ERR)
printf("cant open SIGUSR2");
while(1){
// printf("%2d\n", i);
pause();
// 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("unknow SIGNAL\n");
}
➜ _10_SIGNALS ./kill_exp
received SIGUSR1
received SIGUSR2
[1] + 11410 suspended (signal) ./kill_exp
➜ _10_SIGNALS
[1] + 11410 killed ./kill_exp
➜ _10_SIGNALS ps -a
PID TTY TIME CMD
11410 pts/17 00:00:22