• 函数 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
    ");
        longjmp(jmp,1);     //直接返回,后面不再执行
        printf("fun1 continue
    ");
    }
    void fun2()
    {
        printf("fun2 done
    ");
        longjmp(jmp,2);     //直接返回,后面不再执行
        printf("fun2 continue
    ");
    }
    int main()
    {
        switch(setjmp(jmp)){
            case 1:
                printf("main case 1
    ");
                return;
            case 2:
                printf("main case 2
    ");
                fun1();
                return;
            default:
                printf("default
    ");
                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
    ");
    	longjmp(jmp,1);
    }
    inline void err_sys(char *str)
    {
    	printf("%s
    ",str);
    	exit(-1);
    }
    
    int main()
    {
    	sigset_t oset;
    	sigprocmask(0,NULL,&oset);
    	if(sigismember(&oset,SIGALRM)) printf("SIGALRM in oset
    ");
    	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
    ");
    		err_sys("timeout");
    	}
    	int a=alarm(3);
    	printf("%d
    ",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
    ");
    	siglongjmp(jmp,1);
    }
    inline void err_sys(char *str)
    {
    	printf("%s
    ",str);
    	exit(-1);
    }
    
    int main()
    {
    	sigset_t oset;
    	sigprocmask(0,NULL,&oset);
    	if(sigismember(&oset,SIGALRM)) printf("SIGALRM in oset
    ");
    	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
    ");
    		err_sys("timeout");
    	}
    	int a=alarm(3);
    	printf("%d
    ",a);
    	sleep(4);
    	alarm(0);
    	signal(SIGALRM,prefun);
    	return 0;
    }
    

     0
    sig alrm
    timeout

  • 相关阅读:
    面向对象编程听高翔“面向对象与生活”有感
    .Net调试技巧
    关于排序(简单)
    Http Handler由IIS6到IIS7的使用问题
    也谈【关于 京东员工被离职】另一个角度
    poj1062昂贵的聘礼
    poj1125 Stockbroker Grapevine
    poj1860 Currency Exchange
    poj1258 AgriNet
    poj2485 Highways
  • 原文地址:https://www.cnblogs.com/jokoz/p/4729128.html
Copyright © 2020-2023  润新知