无心中看到了 signal() 函数,感受对这个函数的原型有诸多疑惑,学习一下,顺便分享。函数
1. 原型
Unix系统提供了signal()和sigaction()两个函数来改变对于信号的处理方法。其中signal()是一个基于sigaction()系统调用的glibc库函数,其行为在不一样的Unix操做系统存在差别,对于可移植性有要求的程序不能使用signal()函数。学习
其原型以下:测试
#include<signal.h> void ( *signal(int sig, void (*handler)(int)) )(int);
signal函数的第一个参数sig,要传入但愿修改处理函数的信号编号,第二个参数,是一个无返回值、接受一个int形参的函数指针,指向对sig信号的新处理函数。函数的第二个参数能够有三种选择,第一种是咱们本身定义的信号处理函数,第二种是传入SIG_DFL 表示将以前signal所改变的信号处理方式还原,第三种是传入SIG_IGN,表示处理方式为忽略该信号,内核会直接将信号丢弃,不会传递到进程。操作系统
signal函数的返回值一样是一个无返回值、接受一个int形参的函数指针。当signal()函数成功执行时,返回值是执行signal函数以前的sig信号的处理函数的指针,若是失败,则返回SIG_ERR。指针
对信号处理函数指针作这样的定义,可能便于理解:code
//将sighandler_t定义为返回值为void,接受一个int形参的函数的指针 typedef void (*sighandler_t)(int); //如今咱们能够这样书写signal函数 sighandler_t signal(int sig, sighandler_t handler);
其实glibc里已经有了如上的定义,只须要咱们定义_GUN_SOURCE特性测试宏,就可使用sighandler_t类型。
2.实例
如下用法用于暂时性修改某信号的信号处理函数,在使用完以后,将信号处理函数重置为其原来版本。进程
void newhandler(int sig){ //code to handle the sig } void (*prevhandler)(int); //存储修改以前的信号处理函数 prehandler = signal(SIGINT, newhandler); if(prehandler == SIG_ERR) cerr<<"Error in signal"<<endl; /*如今,对于中断信号的处理已经修改成咱们定义的newhandler函数*/ if(signal(SIGINT, prevhandler) == SIG_ERR) cerr<<"Error in signal"<<endl;