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

本文详细解释了可重入性和不可重入性函数的概念,并通过具体示例对比了两者之间的区别,强调了在多任务环境下确保函数可重入性的必要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘自:嵌入式实时操作系统uCOSII-邵贝贝

可重入性(Reentrancy

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

7
}
*dest = NUL;
}

函数 Strcpy()做字符串复制。因为参数是存在堆栈中的,故函数 Strcpy()可以被多个
任务调用,而不必担心各任务调用函数期间会互相破坏对方的指针。
不可重入型函数的例子如程序 2.2 所示。Swap()是一个简单函数,它使函数的两个形式
变量的值互换。为便于讨论,假定使用的是可剥夺型内核,中断是开着的,Temp 定义为整
数全程变量。
程序清单 2.2 不可重入型函数
int Temp;
void swap(int *x, int *y)
{
Temp = *x;
*x = *y;
*y = Temp;
}

程序员打算让 Swap() 函数可以为任何任务所调用,如果一个低优先级的任务正在执行
Swap()函数,而此时中断发生了,于是可能发生的事情如图 2.6 所示。 [F2.6(1)]表示中断发
生时
Temp 已被赋值 1,中断服务子程序使更优先级的任务就绪,当中断完成时[F2.6(2)],
内核(假定使用的是μC/OS-Ⅱ)使高优先级的那个任务得以运行[F2.6(3)],高优先级的任
务调用 Swap()函数是 Temp 赋值为 3。这对该任务本身来说,实现两个变量的交换是没有问
题的,交换后 Z 的值是 4,X 的值是 3。然后高优先级的任务通过调用内核服务函数中的延
迟一个时钟节拍[F2.6(4)],释放了 CPU 的使用权,低优先级任务得以继续运行[F2.6(5)].
注意,此时 Temp 的值仍为 3!在低优先级任务接着运行时,Y 的值被错误地赋为 3,而不是
正确值 1。
8
图 2.6 不可重入性函数
请注意,这只是一个简单的例子,如何能使代码具有可重入性一看就明白。然而有些情
况下,问题并非那么易解。应用程序中的不可重入函数引起的错误很可能在测试时发现不了,
直到产品到了现场问题才出现。如果在多任务上您还是把新手,使用不可重入型函数时,千
万要当心。
使用以下技术之一即可使 Swap()函数具有可重入性:
z 把 Temp 定义为局部变量
z 调用 Swap()函数之前关中断,调动后再开中断
z 用信号量禁止该函数在使用过程中被再次调用
如果中断发生在
Swap()函数调用之前或调用之后,两个任务中的 XY 值都会是正确

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值