7.2.6信号举例

下面通过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()调用设置的信号处理程序被自动恢复为默认操作,使得随后的同一信号将只执行信号的默认操作。