信号处理函数的返回sigsetjmp/siglongjmp
由于在信号处理期间自动屏蔽了正在被处理的信号,而使用setjmp/longjmp跳出信号处理程序时又不会自动将
信号屏蔽码修改会原来的屏蔽码,从而引起该信号被永久屏蔽。
可以使用sigsetjmp/siglongjmp来解决这一问题。
int sigsetjmp(sigjmp_buf env, int savesigs);
void siglongjmp(sigjmp_buf env, int val);
如果savesigs非0,则sigsetjmp在env中保存进程的当前信号屏蔽字,在调用siglongjmp会从其中恢复保存的信号
屏蔽字。
#include <stdio.h>
#include <signal.h>
#include <setjmp.h> #define ENV_UNSAVE 0
#define ENV_SAVED 1 int flag_saveenv = ENV_UNSAVE;
jmp_buf env; //保存待跳转位置的栈信息 void hand_min15(int); int main()
{
switch(sigsetjmp(env, ))
{
case :
{
printf("sigsetjmp\n");
flag_saveenv = ENV_SAVED;
break;
}
case :
{
printf("return from min+15\n");
break;
}
default:
break;
} signal(SIGRTMIN+, hand_min15); printf("wait for signal\n");
while(); return ;
} void hand_min15(int sig_num)
{
if (flag_saveenv = ENV_UNSAVE)
{
return;
} sleep();
printf("after sleep\n");
siglongjmp(env, );
printf("recv min+15\n");
return;
}
说明:
1、
信号处理函数先检查 flag_saveenv 的值是否为ENV_UNSAVE,如果是,则直接返回,因为此时程序还没来得及保存返回点的栈状态信息。在sigsetjmp之后才将
flag_saveenv设置为ENV_SAVED。如果不这样处理,那么当信号发生在调用sigsetjmp之前时,信号处理函数将返回到未知地点或程序崩溃(可以在sigsetjmp前面加上sleep(20),
可以观察到程序崩溃)。使用siglongjmp从信号处理程序返回时都应该这样处理。
2、
实时信号是可靠的,支持排队
3、

信号处理函数的返回sigsetjmp/siglongjmp的更多相关文章
- 信号处理函数的返回setjmp/longjmp
信号处理函数可以正常返回,也可以调用其他函数返回到程序的主函数中,而不是从该处理程序返回. 正如ANSI C标准所说明的,一个信号处理程序可以返回或者调用abort.exit或longjmp(goto ...
- 函数 setjmp, longjmp, sigsetjmp, siglongjmp
一,相关函数接口 1,setjmp,longjmp,sigsetjmp,siglongjmp #include <setjmp.h> int setjmp(jmp_buf env); ...
- 在信号处理函数中调用longjmp
错误情况及原因分析 前两天看APUE的时候,有个程序要自己制作一个sleep程序,结果在这个程序中就出现了在信号处理函数中调用longjmp函数的情况,结果就出现了错误,具体错误是啥呢,请参见下面这段 ...
- Linux 多线程应用中如何编写安全的信号处理函数
http://blog.163.com/he_junwei/blog/static/1979376462014021105242552/ http://www.ibm.com/developerwor ...
- JNI:在线程或信号处理函数中访问自定义类
在写一个Tomcat应用,类需要被信号处理函数回调,可是在单独的程序中测试没用问题: void OnSingalHandler(int sig) { ... JNIEnv* env=NULL; if ...
- SetConsoleCtrlHandler() -- 设置控制台信号处理函数
http://www.groad.net/bbs/thread-8253-1-1.html 当你在命令行里工作时,经常会输入 Ctrl-C 这个组合键以停止程序的运行.SetConsoleCtrlHa ...
- Linux 多线程应用中如何编写安全的信号处理函数【转】
转自:https://www.cnblogs.com/virusolf/p/4945642.html http://blog.163.com/he_junwei/blog/static/1979376 ...
- Linux信号、信号处理和信号处理函数
信号(signal)是一种软件中断,它提供了一种处理异步事件的方法,也是进程间惟一的异步通信方式.在Linux系统中,根据POSIX标准扩展以后的信号机制,不仅可以用来通知某种程序发生了什么事件,还可 ...
- Entity Framework 6 Recipes 2nd Edition(11-6)译 -> 从一个”模型定义”函数里返回一个复杂类型
11-6.从一个”模型定义”函数里返回一个复杂类型 问题 想要从一个”模型定义”函数返回一个复杂类型 解决方案 假设我们有一个病人(patient)和他们访客(visit)的模型,如 Figure 1 ...
随机推荐
- ThinkPHP5跨控制器调用
1.在application\index\controller\文件夹里新建User.php <?php namespace app\index\controller; class User{ ...
- 20145127 《Java程序设计》第五次实验报告
实验简述: 在本周,我们进行了Java的第五次试验,本次实验的主要内容是结对编程.本次实验的大体过程是: 1.先进行Java的客户端与服务端的代码编写.结对是两个人,一人负责客户端,一人负责服务端. ...
- C#对两种类型动态库的使用
一.托管:如果一个动态库本身是基于.NET的,那么可以直接在工程引用里右键添加引用,如微软的COM技术[因为你依托的是微软的框架,所以需要regsvr32注册] 二.非托管:如果不是基于.NEt的,那 ...
- C# 获取当前IIS请求地址
using System;using System.Collections.Generic;using System.Linq;using System.Web; /// <summary> ...
- P3938 斐波那契
思路 脑子还真的是好东西,自己太笨了 容易发现父亲节点和儿子节点的关系 儿子节点大于父亲节点 儿子节点和父亲节点之差为斐波那契数,且斐波那契数为小于儿子节点的最大的一个 1e12中有60左右的斐波那契 ...
- 基础dp 记录
51nod 1134 最长递增子序列 #include<iostream> #include<cstdio> #include<cstring> #include& ...
- windows 模拟用户会话创建进程
在渗透当中,经常会碰到这样的问题.一个机器,机器上好几个用户,或者域内,想让某个机器的某个会话执行你想要执行的程序,或者中马,以当前会话来上线. 现在模拟如下的一个情况: 严格的DMZ,内网--> ...
- javascript面向对象的一些写法
因为有闭包,能返回函数,所以针对于面向对象的封装,继承,多态三个特性实现,很舒服. 代码如下: <!DOCTYPE html> <html> <head> < ...
- Redis 5种数据结构及其使用场景举例--STRING
String 数据结构是简单的 key-value 类型,value 不仅可以是 String,也可以是数字(当数字类型用 Long 可以表示的时候encoding 就是整型,其他都存储在 sdshd ...
- python 打包成tar包
def make_targz(output_filename, source_dir): with tarfile.open(output_filename, "w:gz") as ...