乱读天书, 不求甚解
周祎骏的个人云笔记
Toggle navigation
乱读天书, 不求甚解
主页
Linux:系统配置
Linux:用户管理
Linux:优化排错
Linux:进程调度
Linux:文件系统
Linux:网络
Linux:系统服务
Linux:安全
Linux:内核
容器:Docker
容器:containerd
容器编排:Kubernetes
IAC:Terraform
大数据:Hadoop
大数据:Zookeeper
大数据:Hbase
消息队列:rsyslog
消息队列:kafka
数据库:MySQL
数据库:MongoDB
搜索引擎:Elasticsearch
时序数据库:OpenTSDB
网站服务:Nginx
编程:Bash
编程:Perl
编程:Python
编程:C
编程:JAVA
编程:Rust
版本控制:gitlab
知识管理:docusaurus
常用小工具
关于我
标签
C 2.13 函数库setjmp.h
2018-06-17 08:23:04
39
0
0
admin
> 使用可以跳跃函数的goto语句 #原理: * C语言每调用一个函数,那么内存上会为这个函数压入一个新的栈存放新的自动变量,当这个函数结束,这个栈就会弹出(释放),这就是为什么函数中的自动变量的生命周期与这个函数的生命周期相同。 * setjmp的原理就是运行setjmp函数的时候会把当前所用的栈的信息保存下来(jmp_buf类型),通过这些信息,在运行longjmp函数的时候,就可以直接在栈上跳过其它的调用的帧,直接回到我们跑setjmp的那个帧。 * 当我们用setjmp强制从一个函数跳跃到另一个函数的时候,全局变量和静态变量与跳转前相同,但是自动变量可能会回滚到调用setjmp前的状态,也可能不回滚,不同机器不一样。 * 想要确保数据不被回滚,用全局变量,静态变量,或者用volatile修饰自动变量(因为寄存器变量**可能**会回滚,普通自动变量可能会被gcc 优化成寄存器变量) #函数 **int setjmp(jmp_buf jmpbuffer)**:保存当前栈的信息,直接调用返回0,从longjmp调用返回非0(longjmp配置的值) **void longjmp(jmp_buf jmpbuffer, int val)**:跳转到setjmp的位置,setjmp的返回值是val ``` #include <stdio.h> #include <setjmp.h> #include <stdlib.h> static jmp_buf jmpbuffer; int global_var = 1; function2() { longjmp(jmpbuffer,3); } function1() { function2(); } main() { static int static_var = 2; register int register_var = 3; //注意,即使申明是寄存器变量,编译器也未必真的作为寄存器变量处理 volatile int volatile_var = 4; if(setjmp(jmpbuffer) == 3 ) { printf("after longjmp: global=%d,static=%d,register=%d,volatile=%d\n",global_var,static_var,register_var,volatile_var); exit(0); } global_var = 11; static_var = 22; register_var = 33; volatile_var = 44; printf("before longjmp: global=%d,static=%d,register=%d,volatile=%d\n",global_var,static_var,register_var,volatile_var); function1(); } ``` **int sigsetjmp(sigjmp_buf env, int savemask)**:与setjmp唯一的区别是savemask非0则在env中保存当前的信号屏蔽字 **void siglongjmp(sigjmp_buf env, int val)**:与longjmp类似,对应sigsetjmp
上一篇:
C 2.12 函数库signal.h
下一篇:
C 2.14 Linux函数库utsname.h,pwd.h,grp.h
文档导航