信号处理函数的返回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 ...
随机推荐
- 02: python3使用email和smtplib库发送邮件
1.1 发送qq邮箱 注:python代理登录qq邮箱发邮件,是需要更改自己qq邮箱设置的.在这里大家需要做两件事情:邮箱开启SMTP功能 .获得授权码 教程链接 1.给单个人发邮件 参考 from ...
- 发现vi出现此错误~/.vim/bundle/YouCompleteMe/third_party/ycmd/ycm_core.so: undefined symbol: clang_getCompletionFixIt
答: 安装更高版本的clang库 sudo apt-get install clang-7 sudo update-alternatives --install /usr/bin/clang clan ...
- url rewrite导致的500.19 0x8007000d
https://stackoverflow.com/questions/13532447/http-error-500-19-iis-7-5-error-0x8007000d It seems you ...
- 【附2】hystrix详述(2)- 配置
一.hystrix在生产中的建议 1.保持timeout的默认值(1000ms),除非需要修改(其实通常会修改) 2.保持threadpool的的线程数为10个,除非需要更多 3.依赖标准的报警和监控 ...
- BZOJ2724 [Violet]蒲公英 分块
题目描述 经典区间众数题目 然而是权限题,所以题目链接放Luogu的 题解 因为太菜所以只会$O(n*\sqrt{n}+n*\sqrt{n}*log(n))$的做法 就是那种要用二分的,并不会clj那 ...
- js函数事件对象
每个函数都有4个默认对象 arguments 保存着实际传入的参数,集合列表 return 有两个功能,打断函数和返回函数值 this 谁调用的函数,this就是谁 event 事件对象 事件 box ...
- booststrap select2的应用总结
本身对前端js了解不是特别多,在项目中,遇到很多前端的问题,有时间整理一下,有不对的地方,不吝赐教,多多批评指正. 在项目中,遇到最多的select下拉框情景,莫过于多选和单选了 单选是很容易理解的, ...
- python 函数返回函数
def hi(name="yasoob"): def greet(): return "now you are in the greet() function" ...
- Linux 安装iostat命令
首先跟你的Linux系统有关 我用的是Red hat系统 记录下最快的安装iostat命令的方式 起初想查看iostat, 提示 iostat: command not found 于是,通过yum ...
- 【转】QT获取系统时间,以及设置日期格式
http://blog.csdn.net/zzk197/article/details/7498593 例如我要在一个label上设置当前时间 QDateTime time = QDateTime:: ...