首页 > 编程知识 正文

可重入函数和不可重入函数的区别,函数可重入

时间:2023-05-06 04:03:26 阅读:190275 作者:3592

在实时系统的设计中,多个任务经常调用同一个函数。 如果某个函数不幸被这样设计,当不同的任务调用此函数时,其他任务可能会修改调用此函数的数据,从而导致意外的结果。这样的函数是不安全的函数,也叫不可重入函数

相反,一定有安全的函数。 此安全函数也称为可重入函数。 那么,什么是可重入函数呢? 重入是由多个任务调用的过程,无需担心数据是否有误。

可重入的函数简单来说就是可中断的函数。 也就是说,在执行此函数的任意时刻中断,然后转移到操作系统计划,执行另一个代码并返回控制时不会发生错误。 不可重入的函数使用全局变量区域、中断向量表等系统资源,因此发生中断时可能会出现问题。 此类函数不能在多任务环境中运行。

也可以这样理解,重入即表示重复进入首先表示此函数是可中断的,然后表示除了使用自己堆栈上的变量外,它不依赖于包括静态在内的任何环境。 这样的函数意味着purecode (纯代码)是可重新读取的,并且可以执行该函数的多个副本。 它们使用单独的堆栈,因此不会相互干扰。 请注意,如果需要访问包含静态的全局变量,请实现互斥手段。 可重入函数在并行执行环境中非常重要,但访问全局变量通常需要一些性能成本。

在创建可重入函数时,如果使用全局变量,则需要通过中断、信号量或关闭p、v操作等手段进行保护。

说明:如果不保护正在使用的全局变量,则无法重新输入此函数。 这意味着,如果多个进程调用此函数,全局变量很可能会处于未知状态。

示例:假设Exam是int全局变量,函数Squre_Exam返回Exam平方值。 那么,以下函数不可重新输入。

int Exam=0; unsignedintexample(intpara ) { unsigned int temp; Exam=para; //(** ) temp=Square_Exam ); 返回时间; }

如果多个进程调用此函数,则结果可能未知。 由于在执行**语句后,使用此函数的另一个进程可能正好处于活动状态,因此当新活动的进程执行此函数时,Exam会赋予另一个para值,从而导致控制“temp=square

int Exam=0; unsignedintexample(intpara ) { unsigned int temp; [请求信号量操作]//(1)锁定Exam=para; temp=Square_Exam (; [信号量释放操作]//returntemp的锁定解除; }

未申请“信号量”表示另一个进程正在为Exam赋值并计算平方,即正在使用此信号,并且在信号释放之前不能继续执行此过程。 申请信号时,可以继续执行,但其他进程必须等待本进程释放信号量后才能使用本信号。

如何确保函数的可重入性:

1 )编写函数时尽量使用局部变量(例如寄存器、栈中的变量);

2 )保护使用的全局变量(例如,采取中断、信号量等互斥的方法),由此结构的函数一定是可复用的函数。

许多满足以下条件的函数无法重新输入(不安全) :

1 )函数体内使用的是静态数据结构

2 )在函数体内调用了malloc (或free )函数

3 )在函数体内调用了标准I/O函数。

如何将不可重入的函数改写为可重入的函数呢? 使不可重入函数可重入的唯一方法是用可重入规则重写。 其实很简单。 只要遵守一些简单易懂的规则,编写的函数就可以重新输入:

1 )不使用全局变量。 因为其他代码很可能会改变这些变量的值。

2 )与硬件交互时,请不要忘记执行类似disinterrupt ()的操作。 那就是关闭硬件中断。 我记得交互式地打开中断。 在某些系列中,这称为“进入/退出核心”。

3 )不能调用其他不可重入的函数。

4 )谨慎使用堆栈。

Linux中常见的可重入函数

参考资料: http://www.embeddedlinux.org.cn

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。