一,相关函数接口

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

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

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

  2. Linux setjmp longjmp

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

  3. setjmp/longjmp 使用

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

  4. setjmp/longjmp

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

  5. 信号处理函数的返回setjmp/longjmp

    信号处理函数可以正常返回,也可以调用其他函数返回到程序的主函数中,而不是从该处理程序返回. 正如ANSI C标准所说明的,一个信号处理程序可以返回或者调用abort.exit或longjmp(goto ...

  6. goto语句的升级版,setjmp,longjmp

    我们知道goto语句是不能跳过函数的,但是在我么C语言的应用中,在不使用汇编的情况下,遇到需要跳出深层循环比如检错机制的时候,有确实想要跨函数跳转,有没有上面办法可以做到呢? 这就是今天要讲的两个库函 ...

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

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

  8. c setjmp longjmp

    http://coolshell.cn/?s=setjmp http://www.cnblogs.com/hazir/p/c_setjmp_longjmp.html double divide(dou ...

  9. setjmp/longjmp 处理异常

    #include <stdio.h> #include <stdlib.h> #include <setjmp.h> jmp_buf jb; void f1() { ...

随机推荐

  1. AOP-----动态代理(转)

    动态代理是实现AOP的绝好底层技术 JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler.其中 InvocationHandler是 ...

  2. Android Intent传递数据

    刚开始看郭大神的<>,实现以下里面的一些例子.Intent传递数据. 我们利用显示的方式进行Intent的启动. 1.启动intent并输入数据. Intent intent=new In ...

  3. jquery easyui filebox 上传附件 + asp.net后台

    form必须加这个属性enctype="multipart/form-data",否则后台获取不到文件 <script> function uploadFiles() ...

  4. android AsyncTask 的使用(转载)

    1 ) AsyncTask实现的原理,和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可 ...

  5. Python之路第四天,基础(4)-装饰器,迭代器,生成器

    装饰器 装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法或者类进行加工.在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象 ...

  6. mongo设计(一)

    原文:http://blog.mongodb.org/post/87200945828/6-rules-of-thumb-for-mongodb-schema-design-part-1 By Wil ...

  7. Method "setAge" failed for object action.RegistAction@1f05562b [java.lang.No....

    大家好,如果大家看到了这篇文字.我觉得大家应该是遇到了该类问题. 首先,NullPointerException 空指针异常. 其次,大家应该是是在使用struts2和hibernate的使用遇到的这 ...

  8. Mindjet 一打开鼠标就动不了解决方法

    在网上查找了一下相关资料,这个主要是Mindjet不支持64位系统造成的,其实就和Windows tablet pc input 这个服务相冲突造成的,临时的解决方法是,win+r (别告诉我你不知道 ...

  9. haproxy hdr_beg 配置

    v-dev-app01:/root# ping www.zjdev.com PING www.zjdev.com (192.168.32.16) 56(84) bytes of data. 64 by ...

  10. POJ 3484 Showstopper(二分答案)

    [题目链接] http://poj.org/problem?id=3484 [题目大意] 给出n个等差数列的首项末项和公差.求在数列中出现奇数次的数.题目保证至多只有一个数符合要求. [题解] 因为只 ...