c 可重入函数,c++ 可重入函数,一篇文章带你了解C语言函数的可重入性

c 可重入函数,c++ 可重入函数,一篇文章带你了解C语言函数的可重入性

本文主要详细介绍了C语言函数的可重入性,非常详细,有一定的参考价值。感兴趣的朋友可以参考一下。

目录

I .不可重入函数。第二,可重入函数。第三,如何写可重入函数。第四,可重入函数与线程安全的关系。第五,为什么malloc和printf不能重入?

一、不可重入函数。

如果我们在一个函数中使用了一个静态变量,这个函数可能在调用另一个函数的过程中被调用,导致中断,那么原来的静态变量在这里被改变,然后返回到主函数,使用的静态变量被改变,导致错误。这种函数称为不可重入函数。

在嵌入式系统的设计中,经常会出现多个任务调用同一个函数的情况。如果这个函数不幸被设计成不可重入的,那么当不同的任务调用这个函数时,调用这个函数的其他任务的数据可能会被修改,从而导致不可预知的后果。

在实时系统设计中,不可重入函数被认为是不安全的函数。

满足下列条件的函数多数是不可重入的:

(1)函数体使用静态数据结构;

(2)在函数体中调用malloc()或free()函数;

(3)在函数体中调用标准的I/O函数。

(4)不能中断的硬件寄存器在函数体中调用,比如串口收发寄存器。

二、可重入函数。

可重入函数可以被多个任务调用,而不用担心数据损坏。可重入函数可以随时中断,一段时间后可以重新运行,不会丢失相应的数据。

重新进入函数或只使用局部变量,即保存在CPU寄存器或堆栈中;或者如果使用了全局变量,应该保护全局变量。

如果函数是可重入的,它必须满足以下必要条件:

1.它不能包含静态(全局)非常数数据。

2.不能返回静态(全局)非常数数据的地址。

3.只能处理调用者提供的数据。作为可重入函数的输入参数,只能由调用者提供,提供的输入数据必须满足以上两个要求。

4.不能依赖单实例模式资源的锁。

5.不能调用不可重入的函数。在函数内部,尽量不要使用malloc和free方法来分配和释放内存。如果使用,通常会导致函数不可重入。

三、如何写出可重入的函数

1.写函数时尽量使用局部变量(比如寄存器和栈中的变量)。不要访问那些全局变量,也不要使用静态局部变量。

2.如果真的需要访问全局变量(包括静态),一定要注意实现互斥。可重入函数在并行运行环境中非常重要,但是访问全局变量通常会牺牲一些性能。在编写可重入函数时,如果使用了全局变量,应该通过关闭中断和信号量(即P和V操作)的方式对其进行保护。

四、函数的可重入性和线程安全的关系

重入和线程安全都与函数处理资源的方式有关。然而,它们之间也有一些不同之处。重入概念会影响函数的外部接口,而线程安全只关心函数的实现。

在大多数情况下,要将一个不可重入的函数变成可重入的函数,必须修改函数接口,以便所有数据都由函数的调用者提供。要把非线程安全的函数改成线程安全的,只需要修改函数的实现部分。通常,添加同步机制是为了防止共享资源被几个线程同时访问。

线程安全和可重入是两个不同的概念。

重入是指在单线程操作系统背景下,重入函数或子程序按照后进先出的线性顺序执行。对于多线程函数或子例程,每个线程的执行时间由操作系统调度,这是不可预测的。但是这个函数的每个线程都会时不时的获取CPU时间片,不断的推进执行进度。

可重入函数不一定是线程安全的;线程安全函数不一定是可重入的。例如,一个函数打开一个文件并读入数据。这个函数是可重入的,因为同时执行它的多个实例不会引起冲突;但是,它不是线程安全的,因为当文件被读入时,其他线程可能正在修改文件,所以为了线程安全,有必要给文件添加“同步锁”。

该函数使用锁定和解锁操作来访问其函数体内的共享资源,因此它是线程安全的,但不能被重入。如果此功能的一个实例在已执行锁定但未执行解锁时停止,并且系统启动此功能的另一个实例,则新实例将在锁定位置等待。如果这个函数是一个中断处理服务,中断处理期间的新中断将导致资源死锁。

五、malloc和printf为什么不可重入

Malloc和printf通常在内部使用全局结构和基于锁的同步。这就是为什么他们不能重新进入。

Malloc函数可以是线程安全的也可以是线程不安全的。两者都不能重新输入:

Malloc在全局堆上操作,两个并发的malloc调用可能返回同一个内存块。(第二个malloc调用应该在获取块的地址之前发生,但是该块没有被标记为不可用)。这违反了malloc的后置条件,所以这个实现不会重入。

printf函数也对全局数据进行操作。任何输出流通常使用一个附加到资源数据的全局缓冲区(终端或文件的缓冲区)。打印过程通常将数据复制到缓冲区,然后刷新缓冲区的序列。

总结

本文到此为止。希望能帮到你,也希望你能多关注我们的更多内容!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • c语言调用退出函数 c语言退出整个程序怎么写
  • c语言中怎么给函数初始化 c语言的初始化语句
  • c语言编写函数计算平均值 c语言求平均函数
  • 详解c语言中的字符串数组是什么,详解c语言中的字符串数组结构,详解C语言中的字符串数组
  • 表达式求值c++实现,c语言实现表达式求值
  • 看懂c语言基本语法,C语言详解,C语言的基本语法详解
  • 用c语言实现快速排序算法,排序算法设计与实现快速排序C语言,C语言实现快速排序算法实例
  • 深入解析c语言中函数指针的定义与使用方法,深入解析c语言中函数指针的定义与使用情况,深入解析C语言中函数指针的定义与使用
  • 描述E-R图,E-R图举例,关于C语言中E-R图的详解
  • 折半查找法C语言,折半查找算法(算法设计题)
  • 折半查找法C语言,c语言折半法查找数据,C语言实现折半查找法(二分法)
  • 扫雷小游戏c++代码设计,c语言扫雷游戏源代码,C语言实现扫雷小游戏详细代码
  • 怎样统计程序代码行数,C语言统计行数,C#程序员统计自己的代码行数
  • 基于c语言的贪吃蛇游戏程序设计,用c语言编写贪吃蛇游戏程序,C语言实现简单的贪吃蛇游戏
  • 图的两种遍历算法,图的遍历算法代码c语言,Python算法之图的遍历
  • 留言与评论(共有 条评论)
       
    验证码: