信号处理函数的返回setjmp/longjmp
信号处理函数可以正常返回,也可以调用其他函数返回到程序的主函数中,而不是从该处理程序返回。
正如ANSI C标准所说明的,一个信号处理程序可以返回或者调用abort、exit或longjmp(goto不支持跳出它所在的函数,
因此不能用来从信号处理程序返回到主函数中)。
int setjmp(jmp_buf env);
int sigsetjmp(sigjmp_buf env, int savesigs);
void longjmp(jmp_buf env, int val);
void siglongjmp(sigjmp_buf env, int val);
使用longjmp可以跳转到setjmp设置的位置。
参数env是一个特殊类型jmp_buf的变量。这一数据类型是某种形式的数组,其中存放的是在调用longjmp时能用来恢复栈状态的所有信息。
一般来说env是一个全局变量,因为需从另一个函数中引用它。我们可以在希望返回的位置使用setjmp,直接调用setjmp时返回0;当从longjmp
返回时,setjmp的返回值是longjmp的第二个参数的值,可以利用这一点使多个longjmp返回到一个setjmp处。
用法演示:
#include <stdio.h>
#include <signal.h>
#include <setjmp.h> jmp_buf env; void hand_min15(int);
void hand_max9(int); int main()
{
switch(setjmp(env))
{
case :
{
printf("setjmp\n");
break;
}
case :
{
printf("return from min+15\n");
break;
}
case :
{
printf("return from max-9\n");
break;
}
default:
break;
} signal(SIGRTMIN+, hand_min15);
signal(SIGRTMAX-, hand_max9); printf("wait for signal\n");
while(); return ;
} void hand_min15(int sig_num)
{
longjmp(env, );
printf("recv min+15\n");
return;
} void hand_max9(int sig_num)
{
longjmp(env, );
printf("recv max-9");
return;
}
信号处理函数没有正常返回,而是调用了longjmp直接跨函数跳转,返回到setjmp处。
kill -s SIGRTMIN+15 5301
kill -s SIGRTMIN+15 5301
kill -s SIGRTMAX-9 5301
kill -s SIGRTMAX-9 5301
输出结果:
setjmp
wait for signal
return from min+15
wait for signal
return from max-9
wait for signal
在第二次kill -s SIGRTMIN+15 5301 时,没有输出内容。原因:
信号处理时会自动屏蔽正在被处理的信号,在信号处理函数返回时把进程的信号屏蔽字恢复。即解除对当前信号的阻塞。
上面的代码中没有让信号处理函数正常返回,而是用longjmp直接跳转,所以进程的信号屏蔽字在第一次收到信号后,就把
信号设置为阻塞并且再也没有恢复,因而再也触发不了信号处理函数了,除非手动将进程对信号的屏蔽去除。如果既想使用
跨函数跳转直接返回,又想避免每次都手动清除信号屏蔽的麻烦,就要使用:
int sigsetjmp(sigjmp_buf env, int savesigs);
void siglongjmp(sigjmp_buf env, int val);
信号处理函数的返回setjmp/longjmp的更多相关文章
- 信号处理函数的返回sigsetjmp/siglongjmp
由于在信号处理期间自动屏蔽了正在被处理的信号,而使用setjmp/longjmp跳出信号处理程序时又不会自动将 信号屏蔽码修改会原来的屏蔽码,从而引起该信号被永久屏蔽. 可以使用sigsetjmp/s ...
- 在信号处理函数中调用longjmp
错误情况及原因分析 前两天看APUE的时候,有个程序要自己制作一个sleep程序,结果在这个程序中就出现了在信号处理函数中调用longjmp函数的情况,结果就出现了错误,具体错误是啥呢,请参见下面这段 ...
- 函数 setjmp, longjmp, sigsetjmp, siglongjmp
一,相关函数接口 1,setjmp,longjmp,sigsetjmp,siglongjmp #include <setjmp.h> int setjmp(jmp_buf env); ...
- setjmp/longjmp 使用
C语言中有一个goto语句,其可以结合标号实现函数内部的任意跳转(通常情况下,很多人都建议不要使用goto语句,因为采用goto语句后,代码维护工作量加大).另外,C语言标准中还提供一种非局部跳转“n ...
- setjmp()/longjmp()的使用方法
setjmp和longjmp.为了让你实现复杂的流控制,程序在系统里面运行完全依靠内存(代码段,全局段,堆存储器,栈存储器)和寄存器的内容(栈指针,基地址,计数器),setjmp保存当前的寄存器里面的 ...
- Linux 多线程应用中如何编写安全的信号处理函数
http://blog.163.com/he_junwei/blog/static/1979376462014021105242552/ http://www.ibm.com/developerwor ...
- Linux setjmp longjmp
/********************************************************************* * Linux setjmp longjmp * 说明: ...
- setjmp/longjmp
1.setjmp/longjmp属于传统的错误处理 2.setjmp/longjmp是对goto语句的补充,goto仅仅能实现局部跳转.setjmp/longjmp能够实现全局跳转 3.setjmp/ ...
- JNI:在线程或信号处理函数中访问自定义类
在写一个Tomcat应用,类需要被信号处理函数回调,可是在单独的程序中测试没用问题: void OnSingalHandler(int sig) { ... JNIEnv* env=NULL; if ...
随机推荐
- 移动互联网消息推送原理:长连接+心跳机制(MQTT协议)
互联网推送消息的方式很常见,特别是移动互联网上,手机每天都能收到好多推送消息,经过研究发现,这些推送服务的原理都是维护一个长连接(要不不可能达到实时效果),但普通的socket连接对服务器的消耗太大了 ...
- 09: python基础补充
1.1 闭包 1.闭包概念 1. 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用,这样就构成了一个闭包 2. 一般情况下,在我们认知当中,如果一个函数 ...
- 06: linux中find查找命令总结
1.在当前目录下查找以txt结尾的文件 find . -name "*.txt" 2.在当前目录下查找所有以字母开头的文件 find . -name "[a-z]*&qu ...
- 用Nodejs连接MySQL(原文链接)
原文链接:http://blog.fens.me/nodejs-mysql-intro/
- 20145106 《Java程序设计》第10周学习总结
教材学习内容总结 什么是计算机网络? 计算机网络,是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享 ...
- devicePixelRatio手机图片模糊的原因
一.移动设备图片模糊问题 手机上图片模糊问题原因就是一个像素在电脑上和手机上代表的实际像素的不同. 我们在样式表中使用的px(独立像素)单位其实并不一定代表着实际的一个像素(物理像素),这还要看硬件的 ...
- 如何安装多个jdk
1.首先去官网下载不同版本的jdk 下载地址:http://www.oracle.com/technetwork/java/javase/archive-139210.html 2.下载后我的安装路径 ...
- java 监控工具 jconsole
如图
- 【Android实验】第一个Android程序与Activity生命周期
目录 第一个Android程序和Activity生命周期 实验目的 实验要求 实验过程 1. 程序正常启动与关闭 2. 外来电话接入的情况 3. 外来短信接入的情况 4. 程序运行中切换到其他程序(比 ...
- JavaScript页面跳转的一些实现方法
第一种 <script language=”javascript” type=”text/javascript”> window.location.href=”login.jsp?back ...