setjmp和longjmp的使用

时间:2021-05-24 11:21:41

问题描述:

         setjmp和longjmp的使用

问题解决:  

    setjmp和longjmp是C语言独有的,只有将它们结合起来使用,才能达到程序控制流有效转移的目的,按照程序员的预先设计的意图,去实现对程序中可能出现的异常进行集中处理。

先来看一下这两个函数的定义吧:

setjmp和longjmp的函数原型在setjmp.h中

函数原型:

int setjmp(jmp_buf envbuf);

setjmp函数用缓冲区envbuf保存系统堆栈的内容,以便后续的longjmp函数使用。setjmp函数初次启用时返回0值。

void longjmp(jmp_buf envbuf, int val);

longjmp 函数中的参数envbuf是由setjmp函数所保存的堆栈环境,参数val设置setjmp函数的返回值。longjmp函数本身是没有返回值的,它执行后跳转到保存envbuf参数的setjmp函数调用,并由setjmp函数调用返回,此时setjmp函数的返回值就是val。

上 面的说明有点拗口,通俗的解释是:先调用setjmp,用变量envbuf记录当前的位置,然后调用longjmp,返回envbuf所记录的位置,并使 setjmp的返回值为val。当使用longjmp时,envbuf的内容被销毁了。其实这里的“位置”一词真正的含义是栈定指针。

setjmp和longjmp的使用

setjmp和longjmp的使用

注:

      以上实现代码之间跳转,longjmp 跳转到setjmp 之后,从setjmp 开始执行

运行结果如下:

setjmp和longjmp的使用

注:

     如上实现是kill -INT pid ,SIGINT事件,然后longjmp执行

接下来,使用kill -ALRM  pid 输出alram...,end here... 继续for循环。

使用setjmp和longjmp会屏蔽信号,在这里kill -INT pid 之后,下一次再使用kill -INT pid

无法捕捉到该信号,实现信号不被屏蔽需要使用sigsetjmp 和 siglongjmp

具体源文件:

setjmp和longjmp的使用