9.2.2 信号函数signal详解

信号处理函数的定义为:

void signal_handler(int signum)

可以理解为:参数为int型,返回值为void型的函数;

信号函数signal()定义如下:

void ( *signal( int signum,void (*handler)(int) ) ) (int);
signum :信号值;
handler:针对信号值定义的信号处理函数

该函数可以理解为:

1.最外层:void (*signal() ) (int),这是一个指向参数为int,返回值为void型的函数指针,该函数指针又是一个signal函数的返回值,即signal函数执行后,返回一个void (*)(int)的函数指针;

2.signal函数:该函数是带两个参数的函数,第一个参数为int型的信号值,第二个参数为指向用户定义的信号处理函数的指针。对比上面最外层的返回值类型,其指向的函数就是signal的第二个参数指向的函数。总体理解为signal内部把信号signum传递给信号处理函数handler,然后signal函数返回指针,就指向信号处理函数handler,最后开始执行handler。

对比上述两个函数指针指向的函数类型和信号处理函数定义类型,二者相同,即函数指针都是指向信号处理函数的。

书中使用了typedef简化函数指针表达:

先看一个typedef定义函数指针类型的例子:

typedef int (*pointer) (int)

可以理解为 pointer等价于int (*)(int),声明pointer p 就等价于int (*p1)(int)。 

接下来:使用typedef定义void (*)(int):

typedef void (*sighandler_t) (int);
sighandler_t signal(int signum,sighandler_t handler);

 示例操作:

  • signal——test1.c:按下CTRL+C,发出SIGINT信号
#include<stdio.h>
#include<signal.h>
#include<stdlib.h>

void sigterm_handler(int sig){
  printf("Have caught sig N.O. %d\n",sig);
  exit(0);      
}
int main(){
  signal(SIGINT,sigterm_handler) ;/*按下CTRL+C将向其发出SIGINT信号*/
  while(1);
  return 0; 
}

 

 

 

使用gcc signal_test1.c -o signal_test1 生成可执行文件,./signal_test1执行文件:

 

 

观察到 信号值为2。

  •  signal——signal_test2.c : 异步通知的例子:
#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<signal.h>
#include<fcntl.h>
#include<unistd.h>

#define MAX_LEN 100
void input_handler(int num){
  char data[MAX_LEN];
  int len;
 /*read and printf data from input of STDIN_FILENO*/
  len = read(STDIN_FILENO,&data,MAX_LEN);
data[len]= 0;/*字符串结束标志*/ printf(
"input available: &s\n",data); } int main(){ int oflags; signal(SIGIO,input_handler);/*为SIGIO信号安装input——handler驱动*/ fcntl(STDIN_FILENO,F_SETOWN,getpid());/*本进程为STDIN_FILENO文件的拥有者,内核将信号发送给本进程*/ oflags = fcntl(STDIN_FILENO,F_GETFL);/*启用异步通知机制-对设备设置FASYNC标志*/ fcntl(STDIN_FILENO,F_SETFL, oflags | FASYNC); }

使用命令 gcc signal_test2.c -o signal_test2 ; ./signal_test2 

 异步通知理解:

(1)通过F_SETOWN 这个io控制命令设置设备文件的拥有者为本进程,这样从设备驱动发出的信号才能被本进程接收到。

(2)通过F_SETFL 控制命令设置设备文件支持FASYNC,即异步通知模式。

(3)通过signal()函数连接信号和信号处理函数。

posted @ 2022-09-18 18:31  QianFa01  阅读(1080)  评论(0)    收藏  举报