在C中我知道递归函数,但我听说了重入函数。
那是什么?他们之间的区别是什么?
答案 0 :(得分:22)
当您理解该术语的含义时,更容易记住。
术语“可重入”意味着在功能执行时“重新输入”是安全的,通常是在并发环境中。
换句话说,当两个任务可以同时执行该功能而不会相互干扰时,该功能是可重入的。 当一个任务的执行对另一个任务的影响产生影响时,函数不可重入。通常在使用全局状态或数据时就是这种情况。仅使用局部变量和参数的函数通常是可重入的。
答案 1 :(得分:16)
如果一个函数支持同时执行多个执行线程,则该函数是可重入的。这可能是由于实际的多线程,我在下面使用这个案例,或者由于其他海报所指出的其他事情。多线程是第一个想到的,也许也是最容易理解的,所以我专注于这个案例。
这意味着该函数不能使用静态“全局”数据,因为这些数据将由两个(或多个)并行线程访问,通常会破坏性。重入函数通常有一个显式参数来保存任何特定于调用的状态,而不是静态存储它。
strtok()
是C标准库中函数的经典案例,众所周知不是可重入的。
[编辑]:评论中有一堆见解,澄清和更正,所以请阅读这些内容!感谢大家的帮助。
答案 2 :(得分:10)
最初所说的内容大多是正确的 - 除了它不仅限于多线程(同样,使用锁保护全局数据使其线程安全 - 但不必然是重入的)。 [编辑]他现在修改了他的帖子以解释这个问题: - )
函数也可以作为递归的结果在同一个线程上重新输入 - 直接或间接(即函数调用函数b调用函数c调用函数a)。
当然,如果您在多线程可以调用它的基础上防止重入,那么您也可以获得递归案例。然而,反之亦然。
答案 3 :(得分:10)
在前一次调用返回之前调用函数时,会发生“重新进入”。发生这种情况有三个主要原因:递归(函数调用自身),多线程和中断。递归通常更容易,因为很明显该函数将被重新输入。多线程和中断更加棘手,因为重新进入将是异步的。如其他答案中所述,在大多数情况下,该函数不应修改全局数据(读取全局数据是正常的,如果保护为关键部分,则某些写入的国王是可以的。)
答案 4 :(得分:3)
就是这样:
可以通过多个线程同时调用可重入函数,前提是每次调用该函数都会引用唯一数据。
当每个调用引用共享数据时,多个线程可以同时调用线程安全函数。所有对共享数据的访问都是序列化的。
从Qt手册中无耻地偷走了。但这是一个简短而简洁的定义。基本上,非重入函数也不是recursion-safe
。
现在,什么是recursive
功能?它是一种函数的定义。递归函数是根据它们自己定义的。他们减少输入,调用自己,直到可以计算出基本情况,而无需再次调用自己。
所以我们有两件事。
现在,上面的多线程车辆仅用于同时激活多个功能的目的。但是如果你有一个递归函数,你也同时激活了多个函数。大多数递归函数也必须是可重入的。
答案 5 :(得分:1)
重入函数是一种保证在多线程环境下可以正常工作的函数。 意味着当一个线程访问函数时,另一个线程可以调用它...意味着每个都有单独的执行堆栈和处理... 因此,函数不应包含任何可能损害或干扰执行的静态或共享变量。
可以通过线程调用的平均函数,同时安全地从另一个线程运行......并且正确....希望我已经回答了正确的事情....
当然可以认为重入函数与递归函数不同......完全不同的概念.... 重入函数是一种保证在多线程环境下可以正常工作的函数。 意味着当一个线程访问函数时,另一个线程可以调用它...意味着每个都有单独的执行堆栈和处理... 因此,函数不应包含任何可能损害或干扰执行的静态或共享变量。
表示它不应包含任何静态或共享变量....
可以通过线程调用的平均函数,同时安全地从另一个线程运行......并且正确....希望我已经回答了正确的事情....
当然可以认为重入函数与递归函数不同......完全不同的概念....
了解详情:http://wiki.answers.com/Q/What_is_a_reentrant_function#ixzz1wut38jLF 维基:http://en.wikipedia.org/wiki/Reentrancy_%28computing%29
答案 6 :(得分:-2)
所有重入代码都是递归,但并非所有递归都是可重入的。递归的示例是任何直接或间接调用自身的函数。 re-entant的例子是中断处理程序例程。
答案 7 :(得分:-2)
所有递归代码都是可重入的...但并非所有可重入代码都是递归的。