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

正如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. centos/rhel 6.5(更新至centos 7)下rabbitmq安装(最简单方便的方式)

    vim /etc/hosts 增加 127.0.0.1 hostname 不然启动的时候可能会报如下错误: [root@devel2 rabbitmq]# rabbitmq-server ERROR: ...

  2. 20145307陈俊达《网络对抗》Exp 8 Web基础

    20145307陈俊达<网络对抗>Exp 8 Web基础 基础问题回答 1.什么是表单? 表单是一个包含表单元素的区域,表单元素是允许用户在表单中输入信息的元素,表单在网页中主要负责数据采 ...

  3. 20144303石宇森《网络对抗》MSF基础应用

    20144303石宇森<网络对抗>MSF基础应用 实验后回答问题 一.解释什么是exploit,payload,encode: 我认为exploit就是一个简单的攻击指令,就是对配置所有设 ...

  4. html文件引用本地js文件出现跨域问题的解决方案

    在本地做个小demo,很简单,一个html文件,一个js文件,在html文件中通过<script>标签引入js,但是出现了一个意想不到的问题:浏览器报错—— 一番折腾后,终于弄明白了:加载 ...

  5. 自动化测试框架Cucumber和RobotFramework的实战对比

    转自: http://www.infoq.com/cn/articles/cucumber-robotframework-comparison   一.摘要 自动化测试可以快速自动完成大量测试用例,节 ...

  6. org.apache.axis2.AxisFault: java.lang.Error: Unresolved compilation problem:

    原创:转载请注明出处 今天遇到以下一个异常,找了好长时间,就是不知道什么原因, 在网上搜了好多,也没搜到相关的解决方法. 1.异常展示, org.apache.axis2.AxisFault: jav ...

  7. ros 安装c++编译的可执行文件

    xxx为c++源文件名 install( TARGETS xxx ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTI ...

  8. Could NOT find Bullet (missing: BULLET_DYNAMICS_LIBRARY BULLET_COLLISION_LIBRARY BULLET_MATH_LIBRARY BULLET_SOFTBODY_LIBRARY BULLET_INCLUDE_DIR)

    rosdep where-defined bullet sudo apt-get install libbullet-dev

  9. mysql创建utf8数据库

    1.创建 CREATE DATABASE db_name DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; 2.修改 ALTER DATABASE ...

  10. js焦点事件:onfocus、onblur、focus()、blur()、select()

    焦点:使浏览器能够区分用户输入的对象,当一个元素有焦点的时候,那么他就可以接收用户的输入只有能够响应用户操作额元素才可以接收焦点事件,比如:a button input... onfocus:当元素获 ...