标签:
一,相关函数接口
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); jmp_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
标签:
原文地址:http://www.cnblogs.com/jokoz/p/4729128.html