函数 setjmp, longjmp, sigsetjmp, siglongjmp
一,相关函数接口
1,setjmp,longjmp,sigsetjmp,siglongjmp
#include <setjmp.h>
int setjmp(jmp_buf env);
int sigsetjmp(sigjmp_buf env, int savesigs); //savesigs非0时,在env中保存进程当前信号屏蔽字。
void longjmp(jmp_buf env, int val);
void siglongjmp(sigjmp_buf env, int val); //savesigs非0时,该函数会从env中恢复保存的信号屏蔽字。
2,sigprocmask
#include<setjmp.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); 返回 0/-1;
获取当前信号屏蔽字:how任意值,set==NULL,当前信号屏蔽字保存在*oldset中
修改当前信号屏蔽字:*set != NULL,how: SIG_BLOCK,并集;SIG_UNBLOCK,交集;SIG_SETMASK,新值。
3,信号集管理
#include <signal.h>
int sigemptyset(sigset_t *set);清空
int sigfillset(sigset_t *set);全集
int sigaddset(sigset_t *set, int signum);添加
int sigdelset(sigset_t *set, int signum);删除
int sigismember(const sigset_t *set, int signum);测试信号是否在集合中
4,查询挂起信号集
#include <signal.h>
int sigpending(sigset_t *set); 返回 0/-1,*set保存挂起信号集
5,设置定时器
#include <unistd.h>
unsigned int alarm(unsigned int seconds); 返回 0 或者以前设置的闹钟时间的剩余秒数
seconds定时器时间秒数
int pause(void); 挂起调用进程直到捕捉到一个信号。
6,发送信号
#include<signal.h>
int raise(int signo) 给进程自身发送信号。
int kill(pid_t pid,int signo) 发送信号给进程或组
pid>0,发送信号给进程ID为pid的进程
pid==0,发送进程给本组所有进程(不包括系统进程集)
pid==-1,有权发送信号的所有进程(不包括系统进程集)
pid<0,有权发送信号的所有进程(不包括系统进程集)和进程ID为-pid的进程
1,setjmp,longjmp一般应用
#include<stdio.h>
#include<stdlib.h>
#include<setjmp.h>
jmp_buf jmp;
void fun1()
{
printf("fun1 done\n");
longjmp(jmp,1); //直接返回,后面不再执行
printf("fun1 continue\n");
}
void fun2()
{
printf("fun2 done\n");
longjmp(jmp,2); //直接返回,后面不再执行
printf("fun2 continue\n");
}
int main()
{
switch(setjmp(jmp)){
case 1:
printf("main case 1\n");
return;
case 2:
printf("main case 2\n");
fun1();
return;
default:
printf("default\n");
break;
}
fun2();
}
default
fun2 done
main case 2
fun1 done
main case 1
2,信号处理中的应用,longjmp返回时,会把信号加入信号屏蔽字中
#include<stdio.h>
#include<stdlib.h>
#include<setjmp.h>
#include<unistd.h>
#include<signal.h>
typedef void (*sigfun)(int);
jmp_buf jmp; void sig_alrm(int signo)
{
printf("sig alrm\n");
longjmp(jmp,1);
}
inline void err_sys(char *str)
{
printf("%s\n",str);
exit(-1);
} int main()
{
sigset_t oset;
sigprocmask(0,NULL,&oset);
if(sigismember(&oset,SIGALRM)) printf("SIGALRM in oset\n");
sigfun prefun=signal(SIGALRM,sig_alrm);
if(prefun==SIG_ERR) err_sys("signal(SIGALRM) error");
if(setjmp(jmp)!=0){
sigprocmask(0,NULL,&oset);
if(sigismember(&oset,SIGALRM)) printf("SIGALRM in oset\n");
err_sys("timeout");
}
int a=alarm(3);
printf("%d\n",a);
sleep(4);
alarm(0);
signal(SIGALRM,prefun);
return 0;
}
0
sig alrm
SIGALRM in oset 说明处理的信号已经自动加入了信号屏蔽字中
timeout
2,信号处理中,使用sigsetjmp, siglongjmp可以避免“自动加入“
#include<stdio.h>
#include<stdlib.h>
#include<setjmp.h>
#include<unistd.h>
#include<signal.h>
typedef void (*sigfun)(int);
sigjmp_buf jmp; void sig_alrm(int signo)
{
printf("sig alrm\n");
siglongjmp(jmp,1);
}
inline void err_sys(char *str)
{
printf("%s\n",str);
exit(-1);
} int main()
{
sigset_t oset;
sigprocmask(0,NULL,&oset);
if(sigismember(&oset,SIGALRM)) printf("SIGALRM in oset\n");
sigfun prefun=signal(SIGALRM,sig_alrm);
if(prefun==SIG_ERR) err_sys("signal(SIGALRM) error");
if(sigsetjmp(jmp,1)!=0){
sigprocmask(0,NULL,&oset);
if(sigismember(&oset,SIGALRM)) printf("SIGALRM in oset\n");
err_sys("timeout");
}
int a=alarm(3);
printf("%d\n",a);
sleep(4);
alarm(0);
signal(SIGALRM,prefun);
return 0;
}
0
sig alrm
timeout
函数 setjmp, longjmp, sigsetjmp, siglongjmp的更多相关文章
- 信号处理函数的返回sigsetjmp/siglongjmp
由于在信号处理期间自动屏蔽了正在被处理的信号,而使用setjmp/longjmp跳出信号处理程序时又不会自动将 信号屏蔽码修改会原来的屏蔽码,从而引起该信号被永久屏蔽. 可以使用sigsetjmp/s ...
- Linux setjmp longjmp
/********************************************************************* * Linux setjmp longjmp * 说明: ...
- setjmp/longjmp 使用
C语言中有一个goto语句,其可以结合标号实现函数内部的任意跳转(通常情况下,很多人都建议不要使用goto语句,因为采用goto语句后,代码维护工作量加大).另外,C语言标准中还提供一种非局部跳转“n ...
- setjmp/longjmp
1.setjmp/longjmp属于传统的错误处理 2.setjmp/longjmp是对goto语句的补充,goto仅仅能实现局部跳转.setjmp/longjmp能够实现全局跳转 3.setjmp/ ...
- 信号处理函数的返回setjmp/longjmp
信号处理函数可以正常返回,也可以调用其他函数返回到程序的主函数中,而不是从该处理程序返回. 正如ANSI C标准所说明的,一个信号处理程序可以返回或者调用abort.exit或longjmp(goto ...
- goto语句的升级版,setjmp,longjmp
我们知道goto语句是不能跳过函数的,但是在我么C语言的应用中,在不使用汇编的情况下,遇到需要跳出深层循环比如检错机制的时候,有确实想要跨函数跳转,有没有上面办法可以做到呢? 这就是今天要讲的两个库函 ...
- setjmp()/longjmp()的使用方法
setjmp和longjmp.为了让你实现复杂的流控制,程序在系统里面运行完全依靠内存(代码段,全局段,堆存储器,栈存储器)和寄存器的内容(栈指针,基地址,计数器),setjmp保存当前的寄存器里面的 ...
- c setjmp longjmp
http://coolshell.cn/?s=setjmp http://www.cnblogs.com/hazir/p/c_setjmp_longjmp.html double divide(dou ...
- setjmp/longjmp 处理异常
#include <stdio.h> #include <stdlib.h> #include <setjmp.h> jmp_buf jb; void f1() { ...
随机推荐
- 读书笔记-Coding faster(英文版)
读书笔记-Coding faster(英文版) Getting More Productive with Microsoft visual Studio Author: Zain Naboulsi S ...
- 安装wxWidgets
从官网可下载源码安装包.安装后,建立批处理文件对其进行编译: gvim bwx.bat 内容如下: @echo off set WXWIN=C:\wxWidgets-3.0.2 pushd %WXWI ...
- android studio SVN的搭建
android studio 安装 SVN:http://www.it165.net/pro/html/201404/11412.html http://jingyan.baidu.com/album ...
- hdu 2509 Be the Winner 博弈
题目链接 有n堆苹果, 对于其中的每一堆的x个苹果, 它是放在一条线上的. 你每次可以对一堆苹果进行操作, 可以取y个, 1<=y<=x. 然后如果你是取的一条线上中间的苹果, 那么这一堆 ...
- jQuery代码不能执行,必须在代码之前就要包含jQuery包
<script> $(function () { $("#btnRegister").click(function () { ...
- EL表达式(转)
转自:http://www.cnblogs.com/Fskjb/archive/2009/07/05/1517192.html EL 全名为Expression Language EL 语法很简单,它 ...
- logstash indexer和shipper的配置
[elk@zjtest7-frontend config]$ cat logstash_agent.conf input { file { type => "zj_nginx_acce ...
- StarTeam SDK 13 下载安装
SDK 13据称兼容 StarTeam 11. 下载地址是:ftp://us.ftp.microfocus.com/Starteam/st-sdk-13.0-readme.htm Java用户可以选在 ...
- Android Notivation的使用
官方帮助文档:http://wear.techbrood.com/guide/topics/ui/notifiers/notifications.html 博文推荐:http://blog.csdn. ...
- node配置运行环境变量;
node express 在开发环境和生产环境运行的代码是不一样的, 通常是先配置好的,在开发环境运行一套代码,在生产环境运行另一套代码, 开发环境 development, 生产环境producti ...