• siglongjmp和sigsetjmp 用法


    1. 引入原因

    由于在信号处理期间自动屏蔽了正在被处理的信号,而使用setjmp/longjmp跳出信号处理程序时又不会自动将

    信号屏蔽码修改会原来的屏蔽码,从而引起该信号被永久屏蔽。

    可以使用sigsetjmp/siglongjmp来解决这一问题。

    2. 语法

    #include<setjmp.h>
    void siglongjmp(sigjmp_buf env,int val);
    int sigsetjmp(sigjmp_buf env,int savemask);

    POSIX标准没有为siglongjmp定义错误。sigsetjmp被直接激活是返回0,通过siglongjmp被激活是返回参数val的值。

    3. 与setjmp和longjmp之间区别

    这两个函数与setjmp和longjmp之间的唯一区别是sigsetjmp增加了一个参数。如果savemask非0,则sigsetjmp在env中保存进程的当前信号屏蔽字调用siglongjmp时,如果带 非0 savemask的sigsetjmp调用已经保存了env,则siglongjmp从其中恢复保存的信号屏蔽字

    /*
     * sigExpGotoT.c
     *
     *  Created on: 2020年7月30日
     *      Author: zhuying10
     */
    
    #include <stdio.h>
    #include <signal.h>
    #include <setjmp.h>
    
    jmp_buf env;
    void handler (int signal) {
        printf("caught exception
    ");
        longjmp(env, 2);
    }
    
    int main(int argc, char* argv[]) {
        {
            struct sigaction sa = {};
            sa.sa_handler = handler;
            //sigemptyset(&sa.sa_mask);
            //sa.sa_flags = 0;
            if(sigaction(SIGFPE, &sa, NULL) == -1) {
                perror("sigaction");
            }
        }
    
        if (0 == setjmp(env)) {
            int a = 3/(argc - 1);
            printf("a is %d
    ", a);
        } else {
            //exception
            printf("in exception
    ");
        }
    
        return 1;
    }
    int setjmp(jmp_buf env) 建立本地的jmp_buf缓冲区并且初始化,用于将来跳转回此处。这个子程序保存程序的调用环境于env参数所指的缓冲区,env将被longjmp使用。如果是从setjmp直接调用返回,setjmp返回值为0。如果是从longjmp恢复的程序调用环境返回,setjmp返回非零值。
    void longjmp(jmp_buf env, int value) 恢复env所指的缓冲区中的程序调用环境上下文,env所指缓冲区的内容是由setjmp子程序调用所保存。value的值从longjmp传递给setjmplongjmp完成后,程序从对应的setjmp调用处继续执行,如同setjmp调用刚刚完成。如果value传递给longjmp零值,setjmp的返回值为1;否则,setjmp的返回值为value

    当使用longjmp的时候,j的内容被销毁。

    这种方法看起来与goto相似,但是是有区别的,区别如下:

    (1)goto语句不能跳出C语言当前的函数。

    (2)用longjmp只能跳回曾经到过的地方。在执行setjmp的地方仍留有一个过程活动记录。从这个角度上讲,longjmp更象是“从何处来”,而不是“要往哪去”。另外,longjmp接受一个额外的整形参数并返回它的值,这可以知道是由longjmp转移到这里的还是从上一条语句执行后自然执行到这里的。

  • 相关阅读:
    shapely and geos break在distance方法
    linux运维
    【未完待补充】linux 设置So动态库链接路径
    用python建立最简单的web服务器
    nginx + keepalived 双机热备
    nagios监控linux主机监控内存脚本
    linux普通用户权限设置为超级用户权限方法、sudo不用登陆密码
    zato server启动后自动关闭问题解决
    Linux下几种文件传输命令 sz rz sftp scp
    python风味之大杂烩
  • 原文地址:https://www.cnblogs.com/guxuanqing/p/12013466.html
Copyright © 2020-2023  润新知