Recursion 重入与递归
说每个递归函数都需要可重入是真的吗?一点也不 例如,为什么递归函数不能有静态数据?它是否应该不能锁定关键部分 考虑:Recursion 重入与递归,recursion,reentrancy,Recursion,Reentrancy,说每个递归函数都需要可重入是真的吗?一点也不 例如,为什么递归函数不能有静态数据?它是否应该不能锁定关键部分 考虑: sem_t mutex; int calls = 0; int fib(int n) { down(mutex); // lock for critical section - not reentrant per def. calls++; // global varible - not reentrant per def. up(mutex);
sem_t mutex;
int calls = 0;
int fib(int n)
{
down(mutex); // lock for critical section - not reentrant per def.
calls++; // global varible - not reentrant per def.
up(mutex);
if (n==1 || n==0)
return 1;
else
return fib(n-1) + fib(n-2);
}
这并不是说编写递归可重入函数很容易,也不是说它是一种常见的模式,也不是说以任何方式推荐它。但这是可能的。不,我记得有一个阶乘函数可以处理静态(全局)变量。拥有静态(全局)变量不利于重入,而且函数仍然是递归的
global i;
factorial()
{ if i == 0 return 1;
else { i = i -1; return i*factorial();
}
此函数是递归的,不可重入。“重入”通常意味着两个不同的线程可以同时多次输入此函数 为了可重入,它必须做一些事情,比如保护/锁定对静态的访问 另一方面,递归函数不需要保护/锁定对静态的访问,因为它一次只执行一条语句
所以:不,不完全是这样。可重入函数需要能够处理不同线程的并发执行
递归函数必须能够在其仍在运行时处理条目,但访问是以受控方式完成的,而不是由其他线程完成的。如果“可重入”表示对该函数的进一步调用可能在前一个调用结束之前开始,则是的,所有递归函数都是可重入的,因为递归在这个意义上意味着重入
然而,“可重入”有时被用作“线程安全”的同义词,它引入了许多其他需求,从这个意义上说,答案是否定的。在单线程递归中,我们有一个特殊情况,即一次只执行一个函数“实例”,因为“空闲”堆栈上的每个实例都在等待其“子”实例返回。重新标记为可能的作业。不是作业,只是我的一个问题。不再上学了;在WorkRetaged:Recursion=>RecursionReentrant函数为什么不应该有静态数据?丹尼尔:这与定义相反:除非你有一个不同的定义。那页很荒谬(查看讨论页)。考虑API来访问文件系统——它们访问共享全局数据,但可以从多个线程/进程同时调用。添加互斥不会使可重入:一个线程将返回错误的结果,如果另一个线程仍在函数中使用/。如果文件系统是线程安全的,因为它使用锁来保护静态数据,那么这是因为访问静态数据的子例程本身不可重入(这就是它们需要保护的原因)。可以有线程安全的,但不可重入的函数(即使是单线程应用程序)。事实上,可重入和线程安全不是一回事: