可重入函数与不可重入函数

 一. 不可重入函数

  1.1. 什么是不可重入函数

    a. 在实时系统的设计中,常常会出现多个任务调用同一个函数的状况。若是有一个函数不幸被设计成为不可重入这样:那么不一样任务调用这个函数时可能修改其余任务调用这个函数的数据,从而致使不可预料的后果。这样的函数是不安全的函数,也叫不可重入函数。安全

  1.2. 不可重入函数产生

    1.2.1. 知足下列条件的函数多数是不可重入的数据结构

      a. 函数体内使用了静态的数据结构;ide

      b. 函数体内调用了malloc()或者free()函数(malloc和free为不可重入函数);函数

      c. 函数体内调用了标准I/O函数。设计

二. 可重入函数

  2.1. 什么是可重入函数

    a. 可重入函数能够被一个以上的任务调用,而没必要担忧数据被破坏。可重入函数任什么时候候均可以被中断,一段时间之后又能够运行,而相应的数据不会丢失。可重入函数或者只使用局部变量,即保存在CPU寄存器中或堆栈中;或者使用全局变量,则要对全局变量予以保护进程

  2.2. 如何写出可重入函数

    a. 在函数体内不访问那些全局变量,不使用静态局部变量,坚持只使用缺省态(auto)局部变量,写出的函数就将是可重入的。若是必须访问全局变量,记住利用互斥信号量来保护全局变量。或者调用该函数前关中断,调用后再开中断。it

三. 实例分析

   假设 Exam 是 int 型全局变量,函数 Squre_Exam 返回 Exam 平方值。那么以下函数不具备可重入性:class

 

int Exam = 0;  
unsigned int example( int para )   
{   
    unsigned int temp;  
    Exam = para; // (**)  
    temp = Square_Exam( );  
    return temp;  
}

分析:此函数若被多个进程调用的话,其结果多是未知的,由于当(**)语句刚执行完后,另一个使用本函数的进程可能正好被激活,那么当新激活的进程执行到此函数时,将使 Exam 赋与另外一个不一样的 para 值,因此当控制从新回到 “temp = Square_Exam( )” 后,计算出的temp极可能不是预想中的结果。此函数应以下改进:

int Exam = 0;  
unsigned int example( int para )   
{  
    unsigned int temp;  
    [申请信号量操做] //(1)  加锁  
    Exam = para;  
    temp = Square_Exam( );  
    [释放信号量操做] //     解锁   
    return temp;  
}

  申请不到“信号量”,说明另外的进程正处于给 Exam 赋值并计算其平方过程当中(即正在使用此信号),本进程必须等待其释放信号后,才可继续执行。若申请到信号,则可继续执行,但其它进程必须等待本进程释放信号量后,才能再使用本信号。变量