一,相关函数接口

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. android开发Tost工具类管理(一)

    Tost工具类管理: package com.gzcivil.utils; import android.content.Context; import android.widget.Toast; / ...

  2. 跳跃表 C#

               虽然avl树和红黑树在数据搜索和排序方面都是有效的数据结构,但是都显得特别麻烦,跳跃表就显得特别简单,虽然简单 不影响他性能,在平均情况下,其插入.删除.查找数据时间复杂度都是O ...

  3. 享受一下大神的感觉, unity中用C#自己封装dll

    第一次写博客,有什么不对的地方,欢迎大家指出 (1)打开vs(本人用的是vs2013)然后建一个项目,如下图所示,选择.ENT3.5的框架,或者低于3.5的,这是因为Unity里面用的框架可能在3.5 ...

  4. HDU 1829 - A Bug's Life

    Problem Description Background Professor Hopper is researching the sexual behavior of a rare species ...

  5. [string]Roman to Integer,Integer to Roman

    一.Roman to Integer Given a roman numeral, convert it to an integer. Input is guaranteed to be within ...

  6. 启动程序的c++方法

    #include <Windows.h> void main() { WinExec( "notepad.exe fitdata.txt", SW_SHOW ); // ...

  7. java中关于窗体居中显示问题

    最近在学着用java写qq聊天程序,首先是登录和聊天界面,书上没有给出居中显示,通过上网查找知道有两种方案 先说第一种方法,也是以前用的方法 /获得屏幕大小Dimension screenSize = ...

  8. 解决Button在IE6、7下的自适应宽度问题

    很早就遇到过这么个小问题,但由于其并未影响到实际作用和美观就没有正面解决它,现在,我们来试着解决它. 写一个Button,有两种方式:其一,直接button标签:其二,input type=”butt ...

  9. Linux03--文件打包与解压

    参考了<鸟哥的Linux私房菜> 1.压缩命令 gzip(压缩)与zcat(解压并读出来) gzip 可以说是应用度最广的压缩命令了!目前 gzip 可以解开 compress, zip ...

  10. win8 VS2010 配制OpenGL

    glut下载地址: http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip glut.h  ---> C:\Progr ...