Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1425774
  • 博文数量: 842
  • 博客积分: 12411
  • 博客等级: 上将
  • 技术积分: 5772
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-14 14:43
文章分类

全部博文(842)

文章存档

2013年(157)

2012年(685)

分类: LINUX

2012-03-06 16:04:18

linux setjmp和longjmp函数

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。
 
调用longjmp函数时不能使setjmp函数返回0,如果val为0,则setjmp函数返回1。longjmp函数从来不返回,因为它调用后就跳转到setjmp函数保存的堆栈处,恢复堆栈开始执行,所以longjmp函数不会返回。
 
setjmp和longjmp函数使用示例:
#include <stdio.h>
#include <setjmp.h>
 
static jmp_buf buf;
 
int main()
{
    int b;
    b = 3;
 
    if (setjmp(buf) != 0) 
    {
        printf("b=%d\n", b); 
        return 0;
    }
    b = 5;
    longjmp(buf, 1);
 
    return 0;
}
setjmp执行时返回0,执行b等于5,调用longjmp,跳转到setjmp调用,setjmp返回1,打印b=5







setjmp与longjmp结合使用时,它们必须有严格的先后执行顺序,也即先调用setjmp函数,之后再调用longjmp函数,以恢复到先前被保存的“程序执行点”。否则,如果在setjmp调用之前,执行longjmp函数,将导致程序的执行流变的不可预测,很容易导致程序崩溃而退出

 

nt  setjmp(jmp_buf  jmpb) 设置缓冲区来保存堆栈的内容,将保存的上下文存入进程的自身的数据空间(u区),并继续在当前的上下文中执行,一旦碰到了longjmp,进城就从该进程 的u区,取出先前保存的上下文,并恢复该进程的上下文为先前保存的上下文。这时核心将使得进程从setjmp处执行.

void longjmp(jmp_buf jmpb, int retval) 使进程返回到 setjmp处执行,retval 表示此时setjmp的返回值。

longjmp必须在setjmp调用之后,而且longjmp必须在setjmp的作用域之内。具体来说,在一个函数中使用setjmp来初始化一个全局标号,然后只要该函数未曾返回,那么在其它任何地方都可以通过longjmp调用来跳转到 setjmp的下一条语句执行。实际上setjmp函数将发生调用处的局部环境保存在了一个jmp_buf的结构当中,只要主调函数中对应的内存未曾释放 (函数返回时局部内存就失效了),那么在调用longjmp的时候就可以根据已保存的jmp_buf参数恢复到setjmp的地方执行。
setjmp函数的返回值(直接返回时为0,longjmp跳转返回时为longjmp的状态参数retval,根据setjmp的返回值就可以判断程序是正常执行还是进行异常处理。

 


阅读(672) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~