文章目录

  • ​​1.可重入函数与不可重入函数的特点​​
  • ​​2.举例说明​​

1.可重入函数与不可重入函数的特点

  • 那么什么是可重入函数呢?
    所谓可重入函数是指一个可以被多个任务调用的过程,任务在调用时不必担心数据 是否会出错。
  • 不可重入函数在实时系统设计中被视为不安全函数。满足下列条件的函数多数是不可重入的:
    (1)函数体内使用了静态的数据结构;(静态存储区:全局变量+static类型的变量)
    (2) 函数体内调用了malloc()或者free()函数;
    (3) 函数体内调用了标准I/O函数。
  • 如何编写可重入的函数?
    在函数体内不访问那些全局变量,不使用静态局部变量,坚持只使用局部变量,写出的函数就将是可重入的。如果必须访问全局变量,记住利用互斥信号量来保护全局变量。
  • 如何将一个不可重入的函数改写成可重入的函数?
把一个不可重入函数变成可重入的唯一方法是用可重入规则来重写它。其实很简单,只要遵守了几条很容易理解的规则,那么写出来的函数就是可重入的。
1) 不要使用全局变量。因为别的代码很可能覆盖这些变量值。
2) 在和硬件发生交互的时候,切记执行类似disinterrupt()之类的操作,就是关闭硬件中断。完成交互记得打开中断,在有些系列上,这叫做“进入/退出核心”。
3) 不能调用其它任何不可重入的函数。
4) 谨慎使用堆栈。最好先在使用前先OS_ENTER_KERNAL。

2.举例说明

A. 可重入函数
void strcpy(char *lpszDest, char *lpszSrc)
{
while(*lpszDest++=*lpszSrc++);
*dest=0;
}


B. 不可重入函数1
charcTemp;//全局变量
void SwapChar1(char *lpcX, char *lpcY)
{
cTemp=*lpcX;
*lpcX=*lpcY;
lpcY=cTemp;//访问了全局变量
}


C. 不可重入函数2
void SwapChar2(char *lpcX,char *lpcY)
{
static char cTemp;//静态局部变量
cTemp=*lpcX;
*lpcX=*lpcY;
lpcY=cTemp;//使用了静态局部变量
}


D.
unsigned int sum_int( unsigned int base )
{
unsigned int index;
static unsigned int sum = 0; // 注意,是static类型
for (index = 1; index <= base; index++)
sum += index;
return sum;
}
分析:所谓的函数是可重入的(也可以说是可预测的),即只要输入数据相同就应产生相同的输出。
这个函数之所以是不可预测的,就是因为函数中使用了 static变量,因为static变量的特征,
这样的函数被称为:带“内部存储器”功能的的函数。因此如果需要一个可重入的函数,一定要避免
函数中使用 static变量,这种函数中的static变量,使用原则是,能不用尽量不用。
将上面的函数修改为可重入的函数,只要将声明sum变量中的static关键字去掉,变量sum即变为一个
auto类型的变量,函数即变为一个可重入的函数。
当然,有些时候,在函数中是必须要使用static变量的,比如当某函数的返回值为指针类型时,则必须是
static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。