Java重入函数_重入函数
重入函数
可重入函数主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现什么错误;而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断向量表等,所以它如果被中断的话,可能会出现问题,这类函数是不能运行在多任务环境下的。
怎么会有可重入和不可重入的概念呢?在多任务系统下,中断可能在任务执行的任何时间发生;如果一个函数的执行期间被中断后,到重新恢复到断点进行执行的过程中,函数所依赖的环境没有发生改变,那么这个函数就是可重入的,否则就不可重入。在中断前后不都要保存和恢复上下文吗,怎么会出现函数所依赖的环境发生改变了呢?我们知道中断时确实保存一些上下文,但是仅限于返回地址,cpu寄存器等之类的少量上下文,而函数内部使用的诸如全局或静态变量,buffer等并不在保护之列,所以如果这些值在函数被中断期间发生了改变,那么当函数回到断点继续执行时,其结果就不可预料了。
满足下面条件之一的多数是不可重入函数:
(1)使用了静态数据结构;
比如使用或者返回全局变量,静态局部变量
(2)调用了malloc或free;
malloc/free是不可重入的,它们使用了全局变量来指向空闲区。malloc通常会为所分配的存储区维护一个链接表,而插入执行信号处理函数的时候,进程可能正在修改此链接表;
(3)调用了标准I/O函数;
标准I/O库的很多实现都使用了全局数据结构;
(4)进行了浮点运算.
许多的处理器/编译器中,浮点一般都是不可重入的
(浮点运算大多使用协处理器或者软件模拟来实现)。举个例子假设有个硬件寄存器名字叫做FLOAT,用来计算和存放浮点数的中间运算结果假设有这么个函数
void fun()
{
//...
}
这个函数对FLOAT寄存器进行操作,假如第一次执行,有个对浮点数操作运算的结果临时存在FLOAT寄存器中,而就在这时被中断了,而中断函数或者另一个进程也调用fun函数,这时第二次调用的fun函数在执行的过程中就会破坏第一次FLOAT寄存器中的结果,这样当返回到第一次fun函数的时候,结果就不正确了。
在信号处理程序及多线程编程时,要特别注意。考虑这种情况:
1) 信号处理程序A内外都调用了同一个不可重入函数B;B在执行期间被信号打断,进入A
(A中调用了B),完事之后返回B被中断点继续执行,这时B函数的环境可能改变,其结果就不可预料了。
2)
多线程共享进程内部的资源,如果两个线程A,B调用同一个不可重入函数F,A线程进入F后,线程调度,切换到B,B也执行了F,那么当再次切换到线程A时,其调用F的结果也是不可预料的。
在信号处理程序中即使调用可重入函数也有问题要注意。作为一个通用的规则,当在信号处理程序中调用可重入函数时,应当在其前保存errno,并在其后恢复errno。(要了解经常被捕捉到的信号是SIGCHLD,其信号处理程序通常要调用一种wait函数,而各种wait函数都能改变errno。)可重入函数在多线程条件下,函数应当是线程安全的,进一步,更强的条件是可重入的。一个可重入函数保证了在多线程条件下,函数的状态不会出现错误。eg.
in cstatic int tmp;
void swap1(int* x, int* y)
{
tmp=*x;
*x=*y;
*y=tmp;
}
void swap2(int* x, int* y)
{
int
tmp;
tmp=*x;
*x=*y;
*y=tmp;
}
swap1是不可重入的,swap是可重入的。因为在多线程条件下,操作系统会在swap1还没有执行完的情况下,切换到另一个线程中,那个线程可能再次调用swap1,这样状态就错了。
一个函数如果满足以及下条件之一,那么它是不可重入的:
函数中使用了静态变量,无论是全局静态变量还是局部静态变量。
函数返回静态变量。
函数中调用了不可重入函数。
函数是singleton中的成员函数而且使用了不使用线程独立存储的成员变量
总的来说,如果一个函数在重入条件下使用了未受保护的共享的资源,那么它是不可重入的。
什么是可重入性?可重入(reentrant)函数可以由多于一个任务并发使用,而不必担心数据错误。相反,
不可重入(non-reentrant)函数不能由超过一个任务所共享,除非能确保函数的互斥(或者使用信号量,或者在代码的关键部分禁用中断)。可重入函数可以在任意时刻被中断,稍后再继续运行,不会丢失数据。可重入函数要么使用本地变量,要么在使用全局变量时保护自己的数据。
可重入函数:不为连续的调用持有静态数据。不返回指向静态数据的指针;所有数据都由函数的调用者提供。使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。绝不调用任何不可重入函数。
编写可重入函数原则:
1、不要使用静态数据结构,坚持只用局部变量;
2、若必须访问全局变量,利用互斥信号量来保护全局变量;
3、获取得知哪些系统调用是可重入的,在多任务处理程序中都使用安全的系统调用;
4、不调用其它任何不可重入的函数;
5、谨慎使用堆栈。堆栈操作涉及内存分配,稍不留神就会造成益出导致覆盖其他任务的数据,最好先在使用前先OS_ENTER_KERNAL;
6、在和硬件发生交互的时候,切记执行类似disinterrupt()之类的操作,就是关闭硬件中断。完成交互记得打开中断,在有些系列上,这叫做“进入/退出核心”。
Java重入函数_重入函数相关推荐
- java 虚基类_重拾C++之虚函数和虚基类以及抽象类
一.引言 好久没接触过C++了,今天突然要用一点感觉号蛋疼,用惯了python感觉C++一点都不会了. 声明了一个类的对象居然用这种方法,脑子绝对是被驴(python)踢了 class A{ ... ...
- java内联函数_Java之内联函数_内联函数的优缺点
描述 内联函数 1.内联函数就是指函数在被调用的地方直接展开,编译器在调用时不用像一般函数那样,参数压栈,返回时参数出栈以及资源释放等,这样提高了程序执行速度. 2.Java语言中有一个关键字fina ...
- java定义类模板_定义模板——函数模板和类模板
面向对象编程(OOP)和泛型编程都能处理在编写程序时不知道类型的情况.不同之处在于:OOP能处理类型在程序运行之前都未知的情况:而在泛型编程中,在编译时就能获知类型了. 前面介绍的容器.迭代器和算法都 ...
- java欧拉函数_欧拉函数(总结)
定义 欧拉函数ϕ(n)是不超过n且和n互质的正整数的个数.欧拉函数φ(n)的作用就是转化,从而简化运算(小性质:n的所有质因子之和=eular(n)*n/2); 下面直观地看看欧拉函数: n 1 2 ...
- C++_虚继承_虚函数_纯虚函数(多继承的二义性,多态)
基本信息 每一个类都有一个虚表,以及虚表指针; 虚表的内容是编译器决定的,虚表中用于存放虚函数的指针, 程序运行时的类型信息等; 每个多态对象都存放着一个指向当前类型的虚表的指针, 该指针在构造函数中 ...
- mysql 内联函数_内联函数 - freeboy小亮 - 博客园
(1)什么是内联函数? 内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内. (2)为什么要引入内联函数? 当然,引入内联函数的主要目的是:解决程序中函数调用的效率问题.另外,前面我们 ...
- arg是什么函数_不定参数函数实现var_arg系列的宏
电驴的源码日志模块有一个叫 DebugLogError 函数,其签名如下: //代码位于easyMule-master/src/WorkLayer/Log.h 55行void DebugLogErro ...
- bool函数_有趣的函数绝无仅有
靠其强大的功能,灵活的语法,丰富而强大的库Python成为了当前市场上靠前的火热编程语言.Python除了拥有众多的第三方库和方法函数外,自身也带有很多非常有趣的函数,用起来堪称优雅.今天主要为大家分 ...
- onclick=两个函数_[译]React函数组件和类组件的差异
[译]React函数组件和类组件的差异 原文: https://overreacted.io/how-are-function-components-different-from-classes/ 在 ...
- string.h包含哪些函数_多个函数组合拳专治不规则时间转化难题|Excel134
小伙伴们好,今天分享一个关于不规则时间转换的小技巧. 这是Excel学员群里的学员提出的,我觉得这个案例很典型,所以分享给大家,希望能够帮助在此方面有同样困惑的小伙伴. 问题描述:计算A列学习时长的小 ...
最新文章
- css3运动后留下轨迹尾巴_球磨机的工作原理及机内运动轨迹分析
- hbase shell命令扩展(转自http://www.netfoucs.com/cuirong1986/article/details/7986900)
- Windows下Memcached的安装与配置
- 玩转数据结构从入门到进阶四
- Java抽象类与接口的区别
- subst命令镜像虚拟磁盘指南(原创)
- SAP CDS view的文本格式的源代码是如何被ABAP后台解析的
- excel npoi 连接_Net操作Excel_NPOI(示例代码)
- 很气很气——在python中切换selenium中的窗口
- django-单表的增删改查-用户部门表
- SQL Case When Then
- KVM Disk Cache简析
- 2022春节档新片预售总票房达1.08亿
- 【Flink】Flink的 processingTimeTimersQueue 是如何注册数据的
- chrome强制使用HSTS原理
- C# 使用Newtonsoft.Json 对象转json字符串,json字符串转对象
- win7开启不了Aero
- 日本互联网 20 年沧桑路
- 记忆就是记忆!!不要深究!
- 社交之战,结局:被封?,这只是一个开始
热门文章
- SQL——Hibernate SQL增删改查
- 从零基础入门Tensorflow2.0 ----六、30 kaggle 10 monkeys 基础模型搭建与训练
- ArcGIS中修改面图层中相邻面的公共边
- 将print的内容保存到txt文本中
- python的全局变量和局部变量
- python处理遥感数据(NVDI计算、辐射校正)
- CSS学习总结(1)——基本介绍
- GDAL和GeoPandas的安装
- 实习成长之路——SpringBean一:BeanDefinition元信息有什么?除了Bean名称和类型,还有那些Bean的元信息值得关注?
- Glide4.0源码全解析(三),into()方法背后的故事