不可重入性是指函数在被调用时,如果被打断,函数的期待值将被改变。
可重入性是指函数在被调用时,无论中间如何被打断,结果都不会发生改变
一般当函数内出现下列内容,将不可重入:
(1)静态数据结构
一般中断函数中不能有不可重入函数,因此以中断函数为例:
__INTERRUPT func()
{
static int a = 0;
a += 1;
}
当中断调用该函数时,a加了1,但是如果在此函数运行中,再次发生中断,该函数再次被调用,那么最终a就不止加了1,从而导致非期待的结果。
(2)malloc()或者free()函数
因为这两个函数都会操作全局的链表,如果第一次malloc没结束时,再被一次malloc打断,那么两次malloc申请的空间起始地址可能会相同。
(3)调用了标准的I/O函数的
如printf()函数,因为printf调用了FILE *stdout全局缓冲区,如果第一次printf()未执行完,再次执行printf(),那么stdout缓冲区的数据将被改变,第二次printf()执行完后,第一次的printf的内容将发生改变。
(4)进行了浮点运算
浮点运算一般会使用浮点寄存器,如果第一次浮点计算未完成,被打断再次执行浮点计算,那么第二次执行完后,再返回第一次浮点计算,将会出现错误结果
为了预防不可重入函数发生错误,在需要重入的函数中排除以上情况,或者加入锁防止重入
举个可重入函数的例子:
int func(int a, int b)
{
int c = a + b;
return c;
}
此函数中,无论如何被打断,c都是返回a+b的值。因为a,b,c都是临时变量,存在栈中,在执行过程中如果被函数A打断,函数A将会申请新的栈空间,不会改变该段栈空间的内容(错误行为除外),所以他们的值不会变。