Linux中信号处理(一)

已经有差不多一年没有使用 《unix环境高级编程》中的知识了,现在抽个时间大概的复习下《unix环境高级编程》,也顺便记录下,方便以后再复习使用;

信号简介

1、信号是软件中断,提供的是一种处理异步事件的方法;

2、不存在编号为0的信号,在kill函数中对信号0有特殊应用;

3、对信号的处理方法有三种:

a、忽略信号,也就是不做任何处理,SIGKILL/SIGSTOP(即:9/19号信号)不能被忽略;

b、捕捉信号,也就是调用用户开始设计好的信号处理函数去处理;9/19号信号不能被捕捉;

c、系统默认,不做处理,也不设置默认,调用系统定义的处理该信号的方法去执行;(绝大部分默认为终止该进程)

4、可以调用命令:kill -l 来查看系统支持的信号;2号信号 —- ctrl+c —- SIGINT;20号信号 —- ctrl+z —- SIGTSTP;

signal函数

signal函数原型:void (*signal(int signo, void (*func)(int) ) ) (int);

该函数的功能:当信号signo 发生时,调用 func 函数去处理;其实就是对signo的信号进行绑定;

函数分析:

void (*func)(int) 这是一个函数指针,其实就是表示一个函数的入口地址,当信号发生时,跳转到该入口地址去执行;

signo 是信号的编号,指定某个信号;

所以:signal的函数为 signal(int signo, void (*func)(int)) ;我们一般使用的时候也是这样用的,例如:signal(SIGINT, faction);对SIGINT信号进行绑定;

那为什么上面的原型不一样呢,那是因为上面的原型是包括了返回值,而signal的返回值是一个函数指针,带有int参数,返回值为空 的函数指针;其实返回的函数指针就是该信号前一个绑定的处理函数指针;

看下面的程序,能够很好的理解signal函数:

#include<signal.h> #include<stdio.h> void sigFaction(int signo)// 第一次为SIGINT信号绑定的处理函数 {if (signo == 100) // 这里signo不是代表信号,是为了测试signal返回函数指针用的printf("signal ret!\n");if (signo == SIGINT)// 这里是测试SIGINT信号处理方法printf("ctrl + c\n"); } void test(int signo)// 第二次为SIGINT信号绑定的处理函数 {if (signo == SIGINT)printf("test\n"); } int main(void) {if (SIG_ERR == signal(SIGINT, sigFaction) )// 第一次开始为SIGINT信号进行绑定printf("sigint error!\n");// 出错打印sleep(10);// 睡眠会,期间发生ctrl+c 则会调用上面绑定的sigFaction函数进行处理signal(SIGINT, test)(100);// 这里利用signal()函数返回上一次绑定的函数指针,进行调用sigFaction()函数,传入的参数为100;同时为SIGINT绑定test处理函数while(1) pause();// 为了等待信号发生,避免进程终止return 0; }

代码分析:

设计这个代码主要是分析signal()函数原型,第一次为信号SIGINT绑定了sigFaction()函数,当ctrl+c发生时,会调用sigFaction()函数来进行处理的;

然后执行signal(SIGINT, test)(100); 因为signal()函数返回的是上一次为该信号绑定的处理函数指针,所以这里顺便调用下上一次绑定处理函数,传入参数为 100,所以在sigFaction()函数中会打印相应的信息;

同时,这里也会为SIGINT信号进行第二次绑定test处理函数。那么当ctrl + c再次发生时,,就会调用test()函数来进行处理了;

运行结果:

注意:在调试信号程序时,建议还是先看看,这样会很方便调试;

简化理解

如果上面对signal原型分析的还不能理解的话可以试试用typedef来简化下;

根据上面代码:typedef void sigPoint(int); 这里把 void xxx(int)类型的函数统一为 sigPoint函数;

则:void (*signal(int signo, void (*func)(int) ) ) (int); ==== sigPoint *signal(int, sigPoint*);

信号系统处理函数

上面已经说过,对信号响应有三种情况;第一、忽略该信号;第二、捕捉该信号;第三、执行系统默认动作;第二种 捕捉该信号,上面已经讲过,当捕捉到该信号后,执行用户最开始设置好的处理函数;

第一种,忽略该信号,则是把 1强转为函数 SIG_IGN:#define SIG_IGN (void (*)())1;

第三种,执行系统默认动作,则是把0强转为函数SIG_DFL:#define SIG_DFL (void (*)())0

还有一个绑定出错的函数 SIG_ERR:#define SIG_ERR (void (*)()) -1;

转载请注明作者和原文出处,原文地址:

若有不正确之处,望大家指正,共同学习!谢谢!!!

未经一番寒彻骨,焉得梅花扑鼻香

Linux中信号处理(一)

相关文章:

你感兴趣的文章:

标签云: