信号处理函数可以正常返回,也可以调用其他函数返回到程序的主函数中,而不是从该处理程序返回。

正如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的更多相关文章

  1. 信号处理函数的返回sigsetjmp/siglongjmp

    由于在信号处理期间自动屏蔽了正在被处理的信号,而使用setjmp/longjmp跳出信号处理程序时又不会自动将 信号屏蔽码修改会原来的屏蔽码,从而引起该信号被永久屏蔽. 可以使用sigsetjmp/s ...

  2. 在信号处理函数中调用longjmp

    错误情况及原因分析 前两天看APUE的时候,有个程序要自己制作一个sleep程序,结果在这个程序中就出现了在信号处理函数中调用longjmp函数的情况,结果就出现了错误,具体错误是啥呢,请参见下面这段 ...

  3. 函数 setjmp, longjmp, sigsetjmp, siglongjmp

    一,相关函数接口 1,setjmp,longjmp,sigsetjmp,siglongjmp   #include <setjmp.h> int setjmp(jmp_buf env); ...

  4. setjmp/longjmp 使用

    C语言中有一个goto语句,其可以结合标号实现函数内部的任意跳转(通常情况下,很多人都建议不要使用goto语句,因为采用goto语句后,代码维护工作量加大).另外,C语言标准中还提供一种非局部跳转“n ...

  5. setjmp()/longjmp()的使用方法

    setjmp和longjmp.为了让你实现复杂的流控制,程序在系统里面运行完全依靠内存(代码段,全局段,堆存储器,栈存储器)和寄存器的内容(栈指针,基地址,计数器),setjmp保存当前的寄存器里面的 ...

  6. Linux 多线程应用中如何编写安全的信号处理函数

    http://blog.163.com/he_junwei/blog/static/1979376462014021105242552/ http://www.ibm.com/developerwor ...

  7. Linux setjmp longjmp

    /********************************************************************* * Linux setjmp longjmp * 说明: ...

  8. setjmp/longjmp

    1.setjmp/longjmp属于传统的错误处理 2.setjmp/longjmp是对goto语句的补充,goto仅仅能实现局部跳转.setjmp/longjmp能够实现全局跳转 3.setjmp/ ...

  9. JNI:在线程或信号处理函数中访问自定义类

    在写一个Tomcat应用,类需要被信号处理函数回调,可是在单独的程序中测试没用问题: void OnSingalHandler(int sig) { ... JNIEnv* env=NULL; if ...

随机推荐

  1. C++设计模式 之 “组件协作”模式:Template Method、Strategy、Observer

    “组件协作”模式: #现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式. #典型模式: Templ ...

  2. 20145118《Java程序设计》 第7周学习总结

    20145118<Java程序设计> 第7周学习总结 教材学习内容总结 本周学习内容为第十三章,以下为教材内容重点总结: 1.格林威治标准时间简称GMT时间. 2.java.util.Da ...

  3. 20145312《网络对抗》MSF基础

    20145312<网络对抗>MSF基础 实验要求 1.掌握metasploit的基本应用方式 2.掌握常用的三种攻击方式的思路 实验问答 用自己的话解释什么是exploit.payload ...

  4. ACM-ICPC 2018 徐州赛区网络预赛A Hard to prepare(DP)题解

    题目链接 题意:有n个格子拉成一个环,给你k,你能使用任意个数的0 ~ 2^k - 1,规定操作 i XNOR j 为~(i  ^  j),要求相邻的格子的元素的XNOR为正数,问你有几种排法,答案取 ...

  5. POJ1128 Frame Stacking(拓扑排序+dfs)题解

    Description Consider the following 5 picture frames placed on an 9 x 8 array.  ........ ........ ... ...

  6. 【第二章】 第二个spring-boot程序

    上一节的代码是spring-boot的入门程序,也是官方文档上的一个程序.这一节会引入spring-boot官方文档推荐的方式来开发代码,并引入我们在spring开发中service层等的调用. 1. ...

  7. UVa 3349 Snowflake Snow Snowflakes(Hash)

    http://poj.org/problem?id=3349 题意: 给出n片雪花留个角的长度,要求判断是否有一样的雪花. 思路: Hash表的应用. 首先将每个雪花所有角的总长计算出来,如果两片雪花 ...

  8. nginx缓存功能的设置

    首先用的缓存是proxy_cache. 在http段里加入下列几句: [plain] view plain copy   proxy_connect_timeout 5; proxy_read_tim ...

  9. 机器学习-数据可视化神器matplotlib学习之路(五)

    这次准备做一下pandas在画图中的应用,要做数据分析的话这个更为实用,本次要用到的数据是pthon机器学习库sklearn中一组叫iris花的数据,里面组要有4个特征,分别是萼片长度.萼片宽度.花瓣 ...

  10. 用caffe进行图片检索

    1.图片的处理 输入:将自己的图像转换成caffe需要的格式要求:lmdb 或者 leveldb 格式 这里caffe有自己提供的脚本:create_minst.sh 转换训练图片和验证图片的格式,运 ...