美文网首页
setjmp 和 longjmp

setjmp 和 longjmp

作者: 给艺艺一个未来 | 来源:发表于2022-11-26 20:33 被阅读0次

Linux manual page (手册):setjmplongjmp

总览

头文件
setjmp.h

函数

int setjmp(jmp_buf env);
noreturn void longjmp(jmp_buf env, int val);

jmp_buf
jmp_buf 类型是一种数组类型,适合存储恢复调用环境的信息(比如:函数栈-栈帧指针BP和栈顶指针SP,程序指针PC-未来恢复时Jump到的语句地址,其他寄存器信息-通用寄存器等)(不包括:浮点状态标志、打开的文件或任何其他数据的状态)。

详见:setjmp.h

描述

背景
goto 只能在函数内跳转,而不能在函数间跳转,因此 C 语言引入 setjmp 和 longjmp 。

用法
setjmp 使用 jmp_buf 保存当前函数的调用信息,longjmp 使用一个存有函数调用信息的 jmp_buf 跳转到另一个函数并恢复调用。

setjmp

参数:env 为保存函数调用环境信息的 jmp_buf 对象。

返回值:

  • 0 :表示 jmp_buf 的 setjmp 时的返回值。
  • 非零:表示 jmp_buf 的 longjmp 时的返回值(jmp_buf 的 longjmp会再次从 jmp_buf
    的 setjmp处返回),返回值由 longjmp 中的参数 val 指定。详见:longjmp 。

longjmp
参数:env 为另一函数调用环境信息的 jmp_buf 对象,val 为 longjmp 回到 jmp_buf 所存函数的 setjmp 调用处的返回值。

返回值:无返回值,从 jmp_buf 指向的函数中的 setjmp 调用处返回。

上下文切换

context_switch

吐槽一句:简书的markdown不好用耶,有办法让下面的代码块能更好看些吗?

#define context_switch(coroutine_a, coroutine_b)                                \
  if (setjmp(coroutine_a->jmp_buf) == 0) {                                      \
      /*                                                                        \
       * setjmp save coroutine a jmp_buf success                                \
       * use longjmp goto coroutine b jmp_buf setjmp and return 1               \
       */                                                                       \
      longjmp(coroutine_b->jmp_buf, 1)                                          \
  }                                                                             \
  /* setjmp is not 0, so return from longjmp, then coroutine b run continue */  \

示例

#include <setjmp.h>

jmp_buf context_main, context_a, context_b;

void pirnt_a();
void print_b();

void main()
{
    if (setjmp(context_main)==0) {
        print_a();
    } else {
        printf("2.return main\n");
   }

    if (setjmp(context_main)==0) {
        print_b();
    } else {
        printf("6.return main\n");
        printf("7.return b from main\n");
        longjmp(context_main, 1);
    }
   
}

void print_a() 
{
    if (setjmp(context_a)==0) {
        printf("1.return main from a\n");
        longjmp(context_main, 1);
    } else {
        printf("4.return a\n");
        printf("5.return main from a\n");
        longjmp(context_b, 1);
   }
}

void print_b() 
{
    if (setjmp(context_a)==0) {
        printf("3.return a from b\n");
        longjmp(context_a, 1);
    } else {
        printf("8.return b\n");
   }
}

相关文章

  • C标准库——

    setjmp.h头文件定义了宏setjmp(), 函数longjmp()和变量类型 jmp_buf, 该变量类型会...

  • [C] C语言的setjmp和longjmp

    (1)setjmp和longjmp setjmp(jmp_buf j)必须首先被调用。它表示“使用变量j记录现在的...

  • 使用setjmp和longjmp

    在做看雪2020 KCTF秋季赛第3题 重返地球时,发现了一对奇怪函数:setjmp3、longjmp。不清楚它们...

  • unix 第七章

    自动变量,寄存器变量,易失变量 volatile setjmp 和 longjmp函数 易失变量容易被改变 所以每...

  • 嵌入式C编程中的异常处理

    我们今天说说一种典型的实现C语言异常处理的方法,即以setjmp()函数和longjmp()函数实现的异常...

  • 非本地跳转函数setjmp和longjmp

    C语言提供了一种用户级的异常控制流形式,称为非本地跳转(nonlocal jump),它可以将控制流直接从一个函数...

  • sigsetjmp siglongjmp

    这两个函数的作用可以类比setjmp和longjmp,只不过这两个函数用在信号处理函数中。 在信号处理函数执行的过...

  • jmp_buf的使用,结构定义为数组

    今天看《C专家编程》第7章第8节,最后提到用setjmp/longjmp从信号终恢复。顺便敲了代码看看效果,就对其...

  • APUE读书笔记-10信号(10)

    15、sigsetjmp和siglongjmp函数 前面,我们描述了setjmp和logjmp函数,这个函数可以用...

  • Chapter 16 Standard Library

    setjmp.h 用于实现类似于goto语句的效果在成为top-level的地方使用 setjmp会将程序的各种状...

网友评论

      本文标题:setjmp 和 longjmp

      本文链接:https://www.haomeiwen.com/subject/hrrnnrtx.html