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

正如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. 20165310 Java实验四 《Android程序设计》

    20165310 实验四 <Android程序设计> 第24章:初识Android 任务一:改写res目录中的内容,Hello World后要显示自己的学号,自己学号前后一名同学的学号 首 ...

  2. WIFI模块对比介绍

    一.ESP8266(官网 https://espressif.com/)1 简介 乐鑫智能互联平台——ESCP 拥有高性能无线SOC,给移动平台设计师带来福音,它 以最低成本提供最大实用性,为WiFi ...

  3. Oracleグラントについて

    権限 権限とはデータベースにログインしたユーザに許可する操作の事です. 例えば.更新や削除は行って欲しくないというユーザには.検索の権限のみ与えるというような使い方をします. Oracleの権限には「 ...

  4. linux下通过命令行上传文件到百度网盘

    一.环境: centos release 6.9 python 2.7.13 二.安装工具bypy sudo pip install bypy 三.使用bypy 3.1 授权 [root@ineedl ...

  5. DPDK的安装与绑定网卡

    DPDK的安装有两种方法: 第一种是使用dpdk/tools/setup.sh选择命令字来安装:第二种是自己手动安装.为了更好地熟悉DPDK,我使用第二种方法. 0.设定环境变量 export RTE ...

  6. Java中ArrayList和LinkedList区别 时间复杂度 与空间复杂度

    一般大家都知道ArrayList和LinkedList的大致区别:      1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构.      2.对于随机访问 ...

  7. Mui --- 页面之间的传值

    A页面 mui.ajax('http://14.50.2.49:80/default/AppLogin?Prm=' + Prm, { data: {}, //dataType: 'json', typ ...

  8. Linux command line exercises for NGS data processing

    by Umer Zeeshan Ijaz The purpose of this tutorial is to introduce students to the frequently used to ...

  9. 装B必备之 快捷键配置

    作为一个程序员 所有程序都用快捷来这是装B必备的无形装B 最为致命.... 开始搞起 第一步配置环境变量 在系统D盘新建一个文件夹  D:\cache; 然后把这个路径 配置上 D:\cache; 最 ...

  10. 解决MVC 时间序列化的方法

    1.全局处理 处理代码 publict static void SetSerializationJsonFormat(HttpConfiguration config) { // Web API co ...