《深入理解计算机系统》第八章 (五)非本地跳转 setjmp longjmp

/* $begin restart */
#include "csapp.h"

sigjmp_buf buf;

void handler(int sig)
{
    siglongjmp(buf, 1);
}

int main()
{
    Signal(SIGINT, handler);

    if (!sigsetjmp(buf, 1))
    printf("starting\n");
    else
    printf("restarting\n");

    while(1) {
    Sleep(1);
    printf("processing...\n");
    }
    exit(0);
}
/* $end restart */

setjmp函数

#include <setjmp.h>

int setjmp(jmp_buf env);

int sigsetjmp(sigjmp_buf env, int savesigs);

setjmp函数在env缓冲区中保存当前调用环境,以供后面的longjmp使用,并返回0。调用环境包括程序计数器、栈指针和通用目的寄存器。


longjmp函数

 #include <setjmp.h>

void longjmp(jmp_buf env, int val);

void siglongjmp(sigjmp_buf env, int val);

longjmp函数从env缓冲区中恢复调用环境,然后触发一个从最近一次初始化env的setjmp调用的返回。


核心要点:

setjmp函数之被调用一次,但返回多次,一次是当第一次调用setjmp,而调用环境保存在缓冲区env中时;一次是为每个相应的longjmp调用。

longjmp函数被调用一次,但从不返回。


非本地返回的意义:

非本地返回的一个重要意义在于允许从一个深层嵌套的函数中立即返回,而不用费力解开调用栈。


例程分析:

setjmp在第一次被调用的时候返回0 ,打印出”starting“

之后如果按下ctrl+c就会发送SIGINT信号,进程接收到该信号后就会调用信号处理程序,信号处理程序执行longjmp,触发setjmp返回,返回值为val,即为1,则进程打印输出restarting。之后继续跳入while循环。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值