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

一、可重入性的含义

可重入函数主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现什么错误;而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断向量表等,所以它如果被中断的话,可能会出现问题,这类函数是不能运行在多任务环境下的。

1、可重入函数
a.不为连续的调用持有静态数据。 
b.不返回指向静态数据的指针;所有数据都由函数的调用者提供。 
c.使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。
d.如果必须访问全局变量,记住利用互斥信号量来保护全局变量。
e.绝不调用任何不可重入函数。

2、不可重入函数
a.函数中使用了静态变量,无论是全局静态变量还是局部静态变量。
b.函数返回静态变量。 
c.函数中调用了不可重入函数。
d.函数体内使用了静态的数据结构;
e.函数体内调用了malloc()或者free()函数;
f.函数体内调用了其他标准I/O函数。
g.函数是singleton中的成员函数而且使用了不使用线程独立存储的成员变量 。
h.总的来说,如果一个函数在重入条件下使用了未受保护的共享的资源,那么它是不可重入的。
i.不可重入函数在实时系统设计中被视为不安全函数。


二、编写可重入函数

1、在写函数时候尽量使用局部变量(例如寄存器、堆栈中的变量),对于要使用的全局变量要加以保护(如采取关中断、信号量等方法),这样构成的函数就一定是一个可重入的函数。
2、防止将函数的参数作为工作变量 。将函数的参数作为工作变量,有可能错误地改变参数内容,所以很危险。对必须改变的参数,最好先用局部变量代之,最后再将该局部变量的内容赋给该参数。
3、检查函数所有参数输入的有效性 。这里的原则是:当A调用B时,由B负责检查参数有效性,但无论A传递什么参数都不会导致函数B意外返回或者程序死掉,且大部分时候A需要检查B的返回值以判断B执行是否成功。
4、避免使用BOOL等具有二义性参数 ,建议自己重新定义,如#define Bool bool,#define True true等。
5、当一个过程(函数)中对较长变量(一般是结构的成员)有较多引用时,可以用一个意义相当的宏代替,可增加编程效率和程序的可读性。如TheReceiveBuffer[FirstSocket].byDataPtr,则# define pSOCKDATA TheReceiveBuffer[FirstScoket].byDataPtr


参考资料:
1、可重入函数
2、函数可重入性及编写规范

你可能感兴趣的:(可重入函数与不可重入函数)