setjmp和longjmp
在C语言的库中,setjmp.h可能很多人都没用过,甚至不知道。今天也是刚好接触到,来记录一下他的作用。
setjmp和longjmp有什么用?
- setjmp
int setjmp(jmp_buf env);
The setjmp() function saves various information about the calling environment (typically, the stack pointer, theinstruction pointer, possibly the values of other registers and the signal mask) in the buffer env for later useby longjmp(). In this case, setjmp() returns 0.
翻译过来就是说,setjmp函数会保存当前的有关调用环境的信息,通常是他堆栈指针、指令指针寄存器值和其他信号掩码。保存造缓冲区env中。等待longjmp调用他们。在这种情况下,返回0。
- longjmp
void longjmp(jmp_buf env, int val);
The longjmp() function uses the information saved in env to transfer control back to the point where setjmp() wascalled and to restore (“rewind”) the stack to its state at the time of the setjmp() call. In addition, anddepending on the implementation (see NOTES), the values of some other registers and the process signal mask maybe restored to their state at the time of the setjmp() call.
longjmp函数使用保存在env中的信息将控制权转移回调用setjmp。此外,,其他一些寄存器的值和进程信号掩码可能会恢复到setjmp调用时的状态。
通俗来说,这两个函数配合起来可以实现跳转的目的,我们来看一下代码:
#include <stdio.h> #include <setjmp.h> jmp_buf jmp; void func(int arg) { printf("arg:%d\r\n", arg); longjmp(jmp, 10); } int main() { int ret = setjmp(jmp); if(ret == 0) func(ret); printf("ret:%d\n", ret); return 0; }
运行结果如下:
从运行结果来看,流程大概如上图所示:在保存好当前环境后,进入了func函数。func函数中返回以前的状:就是返回到setjmp函数,所以ret被置为10。
应用场景
- 异常处理:可以保存一个当前状态,如果遇到错误就返回处理异常。
- 状态机:用于不同状态之间的跳转,比如协程。
优点
基于posix api,是C语言库中的函数:在跳转操作中具有很强的跨平台性。