下面通过Linux提供的系统调用signal(),来说明如何执行一个预先安排好的信号处理函数。Signal()调用的原型是
#include <signal.h>
#include <unistd.h>
void (* signal(int signum, void(*handler)(int)))(int);
signal()的返回值是指向一个函数的指针,该函数的参数为一个整数,无返回值,下面是用户级程序的一段代码。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
int ctrl_c_count=0;
void (* old_handler)(INT);
void ctrl_c(int);
main()
{
int c;
old_handler = signal(SIGINT,ctrl_c);
while ((c=getchar())! = '\n');
printf("ctrl-c count = %d\n",ctrl_c_count);
(void) signal(SIGINT,old_handler);
}
void ctrl_c(int signum)
{
(void)signal(SIGINT,ctrl_c)
++ctrl_c;
}
程序说明:这个程序是从键盘获得字符,直到换行符为止,然后进入无限循环。这里,程序安排了捕获ctrl_c信号(SIGINT),并且利用SIGINT来执行一个ctrl_c的处理函数。当在键盘上敲入一个换行符时,SIGINT原来的操作(很可能是默认操作)才被恢复。Main()函数中的第一个语句完成设置信号处理程序:
old_handler = signal(SIGINT,ctrl_c);
signal()的两个参数是:信号值,这里是键盘中断信号SIGINT;以及一个指向函数的指针,这里是ctrl_c,当这个中断信号出现时,将调用该函数。Signal()调用返回旧的信号处理程序的地址,在此它被赋给变量older_handler,使得原来的信号处理程序稍后可以被恢复。
一旦信号处理程序放在应放的位置,进程收到任何中断(SIGINT)信号将引起信号处理函数的执行。这个函数增加ctrl_c_count变量的值以保持对SIGINT事件出现次数的计数。注意信号处理函数也执行另一个signal()调用,它重新建立SIGINT信号和ctrl_c函数之间的联系。这是必需的,因为当信号出现时,用signal()调用设置的信号处理程序被自动恢复为默认操作,使得随后的同一信号将只执行信号的默认操作。