如何验证Linux Signal可靠信号与不可靠信号
前面章节已经<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可靠信号与不可靠信号相关推荐
- 【B站视频笔记】linux 进程间通信(ipc)信号(软中断信号)signal库函数、可靠信号和不可靠信号、信号集sigprocmask(信号掩码、信号递达Delivery、信号未决Pending)
[视频教程]Linux信号详解(可靠信号.不可靠信号.阻塞信号.信号处理函数) [博文]Linux信号 文章目录 背景 课程笔记 一.如何让程序在后台运行 1.加"&"符号 ...
- 可靠信号与不可靠信号
来自:http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html 一.信号及信号来源 信号本质 信号是软件中断,是在软件层次上 ...
- linux signal(附常见的信号含义)
SIGHUP 终止进程 终端线路挂断 SIGINT 终止进程 中断进程 SIGQUIT 建立CORE文件终止进程,并且生成core文件 SIGILL 建 ...
- linux signal函数用法,linux信号机制之sigaction构造体浅析,signal 函数,信号捕捉.
来自:http://hi.baidu.com/phenix_yw/blog/item/6eb4ca391d1479f23a87ce19.html 信号安装函数sigaction(int signum, ...
- Linux signal 信号列表(sigint,sigtstp..)
我们运行如下命令,可看到Linux支持的信号列表:$ kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) ...
- Linux环境进程间通信(二): 信号--转载
http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html http://www.ibm.com/developerworks ...
- Linux系统编程(四)信号
Linux系统编程(四)信号 一.什么是信号? 1.信号的本质 2.信号来源 硬件来源 软件来源 二.常见信号 1.可靠信号和不可靠信号 2.不可靠信号主要有以下问题: 3.可靠信号与不可靠信号注册机 ...
- linux 可定义信号数,Linux系统编程(20)——信号基本概念
信号及信号来源 信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知 ...
- Linux Signal信号表
[版权申明]转载请附上出处链接 Linux Signal信号表 在终端运行kill -l命令, 可查看Linux支持的信号列表: $kill -l1) SIGHUP 2) SIGINT 3) SIGQ ...
最新文章
- [svc]磁盘接口与RAID
- 英文字母大写 html,英文大小写格式
- plsql oracle服务端,PLSQL Developer + Oracle客户端简易安装方法
- 在VS中建立一个易于管理的C++工程
- 一个ABAP调试器里查看类的静态属性的小技巧
- Codeforces Round #703 (Div. 2) Guessing the Greatest C1 C2 二分
- 在使用Gradle构建的Spring Boot应用程序中覆盖Spring Framework版本
- Leetcode每日一题:7.整数反转
- Atitit.atiInputMethod v2词库清理策略工具 q229
- vue多个html传递参数,vue 项目@change多个参数传值多个事件的操作
- 网课学习:PDF阅读器,Blumind思维导图
- 我的Windows Server 2008激活
- vsftp配置虚拟账户
- 龙须酥nbsp;[我的饮食情节#9352;]
- 什么是jsp,什么是Servlet?jsp和Servlet有什么区别?
- 蚂蚁金服 花呗借呗 招聘公告
- 斥候密报_魔兽世界:解锁德拉诺飞行成就指南,并有宝箱插件分享
- 诺奖罗杰.彭罗斯的量子意识及其他(含朱清时-科学与佛学 77分钟视频)
- SAP推出On-Demand创新软件 瞄准中型企业
- php CI 微信支付扩展 微信扫码支付 jssdk 支付 退款