C语言函数重入
C语言函数重入
- 可重入函数:可以被中断的函数,即这个函数执行时,可以中断其执行,可以由一个或多个任务并发使用,而不比担心数据错误。
- 不可重入函数(不安全函数)
- 不能运行在多任务环境下,除非能保证互斥(使用信号量/代码的关键部分禁用中断)
- 是由于使用了未受保护的系统资源,如全局变量区,中断向量表等。
可重入函数:
- 没有静态数据结构
- 不返回指向静态数据的指针
- 所有函数数据由函数的调用者提供
- 使用auto变量,或通过全局变量的拷贝来保护全局变量
- 若必须访问全局变量,则利用互斥信号保护
- 不调用不可重入函数
不可重入函数有:
如果一个函数在重入条件下使用了未受保护的共享的资源,那么它是不可重入的。
- 函数中使用了静态变量,无论是全局静态变量还是局部静态变量。
- 函数返回静态变量
- 函数中调用了不可重入函数
- 函数体内使用了静态的数据结构
- 函数体内调用了malloc()或者free()函数
- 函数体内调用了其他标准I/O函数
- 函数是singleton中的成员函数,而且使用了不使用线程独立存储的成员变量
不可重入函数改写成可重入函数:
1、不使用全局变量
2、在和硬件发生交互时,可能会发生中断时,先关闭中断(有些系列叫做“进入/退出核心”或者用OS_ENTER_KERNAL/OS_EXIT_KERNAL来描述,这是临界区保护)
3、不调用不可重入函数
4、谨慎使用堆栈,最好在使用前OS_ENTER_KERNAL
中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。中断服务子程序ISR:
__interrupt double compute_area (double radius)
{
double area = PI * radius * radius;
printf("\nArea = %f", area);
return area;
}
错误:
1、ISR没有返回值
如果它有返回值,返回给谁,某种中断源产生中断,系统使用ISR进行处理。ISR是链接在某一个中断源上的,而中断源的产生是随机的,所以ISR并没有一个固定的调用者,也没有固定的返回地址,所以返回值没有用。
2、ISR不能传递参数
3、在许多编译器/处理器中,浮点数是不可重入的。有些不允许在ISR中做浮点运算。
4、ISR应该短、有效率的,做浮点数不明智。
5、printf是不可重入函数。
解释:
1、浮点数:一般浮点运算都是由专门的硬件来完成,举个例子假设有个硬件寄存器名字叫做FLOAT,用来计算和存放浮点数的中间运算结果。
假设有这么个函数
void fun()
{
//...这个函数对FLOAT寄存器进行操作
}
假如第一次执行,有个对浮点数操作运算的结果临时存在FLOAT寄存器中,而就在这时被中断了,而中断函数或者另一个进程也调用fun函数,这时第二次调用的fun函数在执行的过程中就会破坏第一次FLOAT寄存器中的结果,这样当返回到第一次fun函数的时候,结果就不正确了。
2、printf函数
引用全局变量stdout,这是标准输入输出流的一个对象
malloc --------全局内存分配表
free --------全局内存分配表
在unix里面通常都有加上_r后缀的同名可重入函数版本。
C语言函数重入的更多相关文章
- C语言可重入函数和不可重入函数
可重入函数和不可重入函数的概念 在函数中如果我们使用静态变量了,导致产生中断调用别的函数的 过程中可能还会调用这个函数,于是原来的 静态变量被在这里改变了,然后返回主体函数,用着的那个静态变量就被改变 ...
- KEILC51可重入函数及模拟栈浅析
MARK:文章中的红色部分是个人的理解. KEILC51可重入函数及模拟栈浅析 关键字:keilc51,模拟堆栈,可重入函数调用,参数传递,C?XBP,C?ADDXBP 摘要:本文较详细的介绍了kei ...
- c语言中函数参数入栈的顺序是什么?为什么
看到面试题C语言中函数参数的入栈顺序如何? 自己不知道,边上网找资料.下面是详细解释 #include <stdio.h> void foo(int x, int y, int z){ ...
- Chipmunk碰撞回调短时间内重入的解决办法
Chipmunk引擎中碰撞行为可能在细微处与一般认识略有不同. 比如碰撞回调方法可能会重入.不知道方法(函数)重入概念的童鞋可以自行谷哥或度娘. 第一次碰撞方法还未返回,第二次碰撞回调又被调用了.至于 ...
- C语言之可重入函数 && 不可重入函数
可重入函数 在 实时系统的设计中,经常会出现多个任务调用同一个函数的情况.如果这个函数不幸被设计成为不可重入的函数的话,那么不同任务调用这个函数时可能修改其他任 务调用这个函数的数据,从而导致不可预料 ...
- Use Reentrant Functions for Safer Signal Handling(译:使用可重入函数进行更安全的信号处理)
Use Reentrant Functions for Safer Signal Handling 使用可重入函数进行更安全的信号处理 How and when to employ reentranc ...
- Linux 多线程可重入函数
Reentrant和Thread-safe 在单线程程序中,整个程序都是顺序执行的,一个函数在同一时刻只能被一个函数调用,但在多线程中,由于并发性,一个函数可能同时被多个函数调用,此时这个函数就成了临 ...
- reentrant可重入函数
在多任务操作系统环境中,应用程序的各个任务是并发运行的,所以会经常出现多个任务“同时”调用同一个函数的情况.这里之所以在“同时” 这个词上使用了引号,是因为这个歌”同时“的含义与我们平时所说的同时不是 ...
- 函数可重入问题reentrant functions(函数执行过程中可以被中断,允许多个副本)
最近经常听到这个名词,以前也听到过,不过接触更多的是“线程安全问题”,而且本人也一直理解的是两个名字的含义是一样的.今天仔细总结一下这个名词相关的概念. 引用博文:可重入函数和不可重入函数 (http ...
随机推荐
- spring 代理 演变过程
动态代理演变 拿JDBC开事务举例子 最初 写代码 每个CUD 都需要开启事务 所以出现很多累赘代码 因此提出静态代理的构想,把事务交给后台做,程序员只需要 调用update(sql)就行了,upda ...
- Codeigniter MongoDB扩展之使用Aggregate实现Sum方法
本篇文章由:http://xinpure.com/codeigniter-mongodb-extension-using-aggregate-sum-method/ Codeigniter Mongo ...
- php 面象对象类自动加载
//自动加载第一步 function myload($class) { require('./'.$class.'.class.php'); } //注册一个函数为自动触发函数 spl_autoloa ...
- Centos系统安装JDK详细图文教程
1.查询系统默认JDK Centos系统默认会安装OpenJDK,一般建议是安装sun公司的JDK.我们首先检查系统是否安装有jdk并且是OpenJDK版本的,若是,则将它卸载掉并安装上sun公司的j ...
- 点滴积累【C#】---错误日志记录到txt文本里。
效果: 描述:将系统中的错误信息,try catch到日志里面. 代码: [后端代码] using System; using System.Collections.Generic; using Sy ...
- instancetype 对比 id 的好处
转自:http://blog.csdn.net/yangzychina/article/details/8818941 今天研究代码的时候,发现居然返回 instancetype 类型,很惊讶自己学识 ...
- 动态添加定时任务-quartz定时器
Quartz动态添加.修改和删除定时任务 在项目中有一个需求,需要灵活配置调度任务时间,刚开始用的Java自带的java.util.Timer类,通过调度一个java.util.TimerTask任务 ...
- Ecmall二次开发-增删改查操作
Ecmall二次开发-增删改查操作 Model目录includes/models 自己添加需要的model class OrdercomplainModel extends BaseModel //类 ...
- 利用JMX统计远程JAVA进程的CPU和Memory
http://songzi0206.iteye.com/blog/1541636 ******************** 从JAVA 5开始,JDK提供了一些JVM检测的API,这就是有名的java ...
- Powershell分支条件
Where-Object 进行条件判断很方便,如果在判断后执行很多代码可以使用IF-ELSEIF-ELSE语句.语句模板: If(条件满足){如果条件满足就执行代码}Else{如果条件不满足}条件判断 ...