现在的位置: 首页 > 技术文章 > RTOS > 正文

什么是可重入函数,什么是不可重入函数

2013年11月17日 RTOS ⁄ 共 1084字 ⁄ 字号 什么是可重入函数,什么是不可重入函数已关闭评论 ⁄ 阅读 2,383 次

可重入型函数可以被一个以上的任务调用,而不必担心数据的破坏。可重入型函数任何时候都可以被中断,一段时间以后又可以运行,而相应数据不会丢失。可重入型函数或者只使用局部变量,即变量保存在CPU寄存器中或堆栈中。如果使用全局变量,则要对全局变量予以保护。如下程序是一个可重入型函数的例子。

void strcpy(char *dest, char *src)
{
while (*dest++ = *src++) {
;
}
*dest = NUL;
}

函数Strcpy()做字符串复制。因为参数是存在堆栈中的,故函数Strcpy()可以被多个任务调用,而不必担心各任务调用函数期间会互相破坏对方的指针。

不可重入型函数的例子如下程序所示。Swap()是一个简单函数,它使函数的两个形式变量的值互换。为便于讨论,假定使用的是可剥夺型内核,中断是开着的,Temp定义为整数全程变量。

int Temp;
void swap(int *x, int *y)
{
Temp = *x;
*x = *y;
*y = Temp;
}

程序员打算让Swap() 函数可以为任何任务所调用,如果一个低优先级的任务正在执行Swap()函数,而此时中断发生了,于是可能发生的事情如下图所示。表示中断发生时Temp已被赋值1,中断服务子程序使更优先级的任务就绪,当中断完成时,内核(假定使用的是μC/OS-Ⅱ)使高优先级的那个任务得以运行,高优先级的任务调用Swap()函数是Temp赋值为3。这对该任务本身来说,实现两个变量的交换是没有问题的,交换后Z的值是4,X的值是3。然后高优先级的任务通过调用内核服务函数中的延迟一个时钟节拍,释放了CPU的使用权,低优先级任务得以继续运行.注意,此时Temp的值仍为3!在低优先级任务接着运行时,Y的值被错误地赋为3,而不是正确值1。

可重入函数

可重入函数

请注意,这只是一个简单的例子,如何能使代码具有可重入性一看就明白。然而有些情况下,问题并非那么易解。应用程序中的不可重入函数引起的错误很可能在测试时发现不了,直到产品到了现场问题才出现。如果在多任务上您还是把新手,使用不可重入型函数时,千万要当心。

使用以下技术之一即可使Swap()函数具有可重入性:


1. 把Temp定义为局部变量
2. 调用Swap()函数之前关中断,调动后再开中断
3. 用信号量禁止该函数在使用过程中被再次调用

如果中断发生在Swap()函数调用之前或调用之后,两个任务中的X,Y值都会是正确的。

×