什么是可重入函数
可重入函数主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数。如果一个函数执行过程中,被中断服务程序打断,去执行另外一段代码,然后恢复先前的功能,而不妨碍其早期的操作,则称该函数能是可重入的。可重入函数用于硬件中断处理,递归等应用程序。
可重入函数必须满足如下条件:
- 不使用全局和静态数据。虽然没有限制,但一般不建议。因为中断可能会改变某些全局值,之后使用新数据恢复可重入函数的动作过程可能会产生不希望的结果。
- 可重入函数不应修改自己的代码。我们需要函数的动作在整个代码中保持相同。
- 不应该调用另一个不可重入函数。
线程安全性和可重入函数
可重入性与线程安全性不同,但密切相关。函数可以是线程安全的,但仍然不可重入。例如,一个函数可以用互斥体包裹在一起(这避免了多线程环境中的问题),但是如果在中断服务例程中使用该函数,它可能会饿死在等待第一次执行以释放互斥锁。避免混淆的关键是可重入只引用一个执行的线程,这是一个从没有多任务操作系统的时候开始的概念。
不可重入函数
满足下列条件的函数多数是不可重入的:
- 函数使用了全局和静态数据
- 函数调用了malloc()或者free()
- 函数调用了标准I/O函数,比如printf()
示例
下面两个函数是不可重入的,第一个是使用一个全局变量,因此它是不可重入的。第二个是调用一个非重入函数,因此这个函数也不是可重入函数。
int x;
int first_function() {
return x * 50;
}
int second_function() {
return first_function() * 50;
}
稍微修改下,下面两个函数就是可重入函数了。
int first_function(int x) {
return x * 50;
}
int second_function(int x) {
return first_function(x) * 50;
}