前面章节已经<Linux下的Signal信号处理及详解>说了,Linux 下的信号分为可靠信号和不可靠信号,或称为实时信号和非实时信号,信号是从1开始编号的,不存在0号信号。0信号用来测试对应进程是否存在或者是否由权限给其发送信号。

可靠信号是为了弥补Linux的不可靠信号以及用户可使用的信号太少的缺陷。怎样理解可靠与不可靠?下面要引进几个概述。

Linux 不可靠信号

还是前面将的例子,SIGINT信号,只是证明它的不可靠性

#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>#define     MSG         "Catch signal SIGINT processing \n"
#define     MSG_END     "Finished process SIGINT return \n"void time_fun() ;static void sig_handler (int signuum )
{/*在信号处理程序中,尽量不要调用与标准IO相关的和不可重入的函数。STDIN_FILENO:接收键盘的输入STDOUT_FILENO:向屏幕输出*/write ( STDOUT_FILENO , MSG , strlen (MSG) ) ;time_fun();write ( STDOUT_FILENO , MSG_END , strlen (MSG_END) ) ;
}void time_fun()
{long long s = 0 ;long long i ;for ( i= 0 ; i < 500000000L ; i++ ) {s += i ;    }
}int main(int argc, char **argv)
{// 注册信号处理函数if ( SIG_ERR == signal ( SIGINT , sig_handler ) ) {fprintf (stderr , "signal error ") , perror ("") ;exit (1) ;}// 让主程序不退出,挂起,等待信号产生while (1) {pause () ; //使调用进程在接到一信号前挂起。}return 0 ;
}

编译输出:

当我们在执行示例程序的时候,如果在打印完 Catch signal SIGINT processing 之后,我们很快多次按下Ctrl-C。会发现当打印完 Finished process SIGINT return 后,仅会再响应一次信号。这是为什么?为什么我们按下那么多次Ctrl-C却只响应那么一次。原因其时就在于SIGINT是一个不可靠信号。


[1~31]均为不可靠信号。证实了SIGINT不是可靠信号,因为多次发生后会丢失。如何验证信号被屏蔽后多次发生,再解除屏蔽后只会递送一次?需要用到sigprocmask函数。再自己写一个简单的脚本多次发送信号,就可以了。这里就不多进行演示了。

Linux 可靠信号

验证可靠信号,其实就是将第一个程序的注册信号改成SIGRTMIN,再改改信号处理函数中打印的信息,来看看个例子:

// filenam : simple_realiable_signal.cpp
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>#define     MSG         "Catch signal SIGRTMIN processing \n"
#define     MSG_END     "Finished process SIGRTMIN return \n"void  do_too_heavy_work () {long long s = 0 ;long long i;for ( i= 0 ; i < 500000000L ; i++ ) {s += i ;    }
}void sig_handler (int signuum ) {// 在信号处理程序中,尽量不要调用与标准IO相关的,不可重入的函数。write ( STDOUT_FILENO , MSG , strlen (MSG) ) ;do_too_heavy_work();write ( STDOUT_FILENO , MSG_END , strlen (MSG_END) ) ;
}int main(int argc, char **argv) {// 注册信号处理函数if ( SIG_ERR == signal ( SIGRTMIN , sig_handler ) ) {fprintf (stderr , "signal error ") , perror ("") ;exit (1) ;}// 让主程序不退出,挂起,等待信号产生while (1) {pause () ;}return EXIT_SUCCESS ;
}

还有一个脚本,用来发送信号:

#!/bin/bash#过滤出signal的pidpid=$(ps aux|grep realiable_signal | grep -v grep | awk '{print $2}')
#循环发送5次信号for((i=0;i<5;i++))
dokill -34 $pid
done

执行一下看看,首先编译signal

再运行脚本:

看看运行结果:

[32~63]为可靠信号或者叫实时信号。

上面讲讲本质上的原因,或许现在不能很快理解,想详细了解本质上的原因,大家可以去看内核源码的东西,内核里写的才是真实-原理的东西。

总结

在信号处理函数中调用一个非可重入函数,其结果未知的,所以尽量不要在信号处理
函数中使用非可重入函数 , 判断是否是可重入函数有一个简单的原则:

1、函数内部不使用操作静态变量。
2、不使用与标准I/O相关函数。
3、不使用malloc ,free() 函数。
4、不调用其它非可重入函数。

关于可重入的概念,大家自行查找一下,或参考APUE相关章节,这里就不多总结了。

参考:《Unix环境高级编程 第三版》

欢迎关注公众号【程序猿编码】,添加本人微信号(17865354792),回复:领取学习资料。或者回复:进入技术交流群。网盘资料有如下:

如何验证Linux Signal可靠信号与不可靠信号相关推荐

  1. 【B站视频笔记】linux 进程间通信(ipc)信号(软中断信号)signal库函数、可靠信号和不可靠信号、信号集sigprocmask(信号掩码、信号递达Delivery、信号未决Pending)

    [视频教程]Linux信号详解(可靠信号.不可靠信号.阻塞信号.信号处理函数) [博文]Linux信号 文章目录 背景 课程笔记 一.如何让程序在后台运行 1.加"&"符号 ...

  2. 可靠信号与不可靠信号

    来自:http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html 一.信号及信号来源 信号本质 信号是软件中断,是在软件层次上 ...

  3. linux signal(附常见的信号含义)

    SIGHUP     终止进程     终端线路挂断 SIGINT      终止进程     中断进程 SIGQUIT   建立CORE文件终止进程,并且生成core文件 SIGILL      建 ...

  4. linux signal函数用法,linux信号机制之sigaction构造体浅析,signal 函数,信号捕捉.

    来自:http://hi.baidu.com/phenix_yw/blog/item/6eb4ca391d1479f23a87ce19.html 信号安装函数sigaction(int signum, ...

  5. Linux signal 信号列表(sigint,sigtstp..)

    我们运行如下命令,可看到Linux支持的信号列表:$ kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) ...

  6. Linux环境进程间通信(二): 信号--转载

    http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html http://www.ibm.com/developerworks ...

  7. Linux系统编程(四)信号

    Linux系统编程(四)信号 一.什么是信号? 1.信号的本质 2.信号来源 硬件来源 软件来源 二.常见信号 1.可靠信号和不可靠信号 2.不可靠信号主要有以下问题: 3.可靠信号与不可靠信号注册机 ...

  8. linux 可定义信号数,Linux系统编程(20)——信号基本概念

    信号及信号来源 信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知 ...

  9. Linux Signal信号表

    [版权申明]转载请附上出处链接 Linux Signal信号表 在终端运行kill -l命令, 可查看Linux支持的信号列表: $kill -l1) SIGHUP 2) SIGINT 3) SIGQ ...

最新文章

  1. [svc]磁盘接口与RAID
  2. 英文字母大写 html,英文大小写格式
  3. plsql oracle服务端,PLSQL Developer + Oracle客户端简易安装方法
  4. 在VS中建立一个易于管理的C++工程
  5. 一个ABAP调试器里查看类的静态属性的小技巧
  6. Codeforces Round #703 (Div. 2) Guessing the Greatest C1 C2 二分
  7. 在使用Gradle构建的Spring Boot应用程序中覆盖Spring Framework版本
  8. Leetcode每日一题:7.整数反转
  9. Atitit.atiInputMethod v2词库清理策略工具    q229
  10. vue多个html传递参数,vue 项目@change多个参数传值多个事件的操作
  11. 网课学习:PDF阅读器,Blumind思维导图
  12. 我的Windows Server 2008激活
  13. vsftp配置虚拟账户
  14. 龙须酥nbsp;[我的饮食情节#9352;]
  15. 什么是jsp,什么是Servlet?jsp和Servlet有什么区别?
  16. 蚂蚁金服 花呗借呗 招聘公告
  17. 斥候密报_魔兽世界:解锁德拉诺飞行成就指南,并有宝箱插件分享
  18. 诺奖罗杰.彭罗斯的量子意识及其他(含朱清时-科学与佛学 77分钟视频)
  19. SAP推出On-Demand创新软件 瞄准中型企业
  20. php CI 微信支付扩展 微信扫码支付 jssdk 支付 退款

热门文章

  1. 数组遍历 java_数组遍历-Java架构师必看
  2. C/C++项目编译时内存不足解决方案
  3. 汉诺塔+汉诺四塔(C/C++)
  4. 盲人程序员如何编程?全靠每分钟450个单词
  5. HTML5 WebAR魔法相册开发
  6. string转数组,数组转list
  7. 各类木材强度_各类木材特性
  8. android对话框心得,Android ProgressDialog使用总结
  9. Closure(闭包)类详解
  10. thinkphp6路由配置