可重入函数(reentrant function)是一类在多线程或多进程环境中能安全执行的函数。可重入函数具有以下特性:
-
没有静态或全局变量:
- 可重入函数不能依赖于静态或全局变量,因为这些变量可能会在函数执行过程中被其他线程或进程修改。
-
不依赖于不可重入函数:
- 如果一个函数调用了另一个不可重入的函数,那么这个函数也会变成不可重入的。
-
不使用动态内存分配:
- 动态内存分配函数(如
malloc
和free
)通常是不可重入的,因为它们会修改全局堆数据结构。
- 动态内存分配函数(如
-
不使用标准I/O函数:
- 标准输入输出函数(如
printf
和scanf
)通常是不可重入的,因为它们使用全局文件指针和缓冲区。
- 标准输入输出函数(如
-
局部变量存放在堆栈中:
- 所有的局部变量应当存放在堆栈中,以确保每次函数调用都有自己独立的副本。
示例
以下是一个简单的可重入函数示例:
#include <stdio.h>
int factorial(int n) {
if (n == 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
int main() {
int result = factorial(5);
printf("Factorial of 5 is %d\n", result);
return 0;
}
这个递归计算阶乘的函数是可重入的,因为:
- 它只使用局部变量
n
。 - 没有使用静态或全局变量。
- 没有调用其他不可重入的函数。
不可重入函数的示例
下面是一个不可重入函数示例:
#include <stdio.h>
int counter = 0;
void increment() {
counter++;
}
int main() {
increment();
printf("Counter is %d\n", counter);
return 0;
}
这个函数不可重入,因为它依赖于全局变量 counter
。如果在多线程环境中调用 increment
函数,可能会导致数据竞态问题。
可重入函数的使用场景
- 多线程编程:在多线程程序中使用可重入函数可以避免竞态条件和数据一致性问题。
- 中断处理程序:在嵌入式系统中,中断处理程序必须是可重入的,以确保在中断过程中不会出现数据错误。