21

在 CI 中知道递归函数,但我听说过重入函数。

那是什么?他们之间有什么区别?

4

8 回答 8

26

当您了解该术语的含义时,更容易记住。

术语“重入”意味着在函数已经执行时“重新进入”它是安全的,通常是在并发环境中。

换句话说,当两个任务可以同时执行该功能而互不干扰时,该功能就是可重入的。当一个任务的执行对另一个任务的影响产生影响时,一个函数是不可重入的。这通常是使用全局状态或数据时的情况。仅使用局部变量和参数的函数通常是可重入的。

于 2008-11-04T09:30:40.413 回答
16

如果一个函数支持多个执行线程同时“通过”它,那么它就是可重入的。这可能是由于实际的多线程,我在下面使用这种情况,或者由于其他海报指出的其他事情。多线程是第一个想到的,也许也是最容易理解的,所以我专注于那个案例。

这意味着该函数不能使用静态“全局”数据,因为该数据将由两个(或更多)线程并行访问,通常会严重中断。可重入函数通常有一个明确的参数来保存任何特定于调用的状态,而不是静态存储它。

strtok()是 C 标准库中众所周知的不可重入函数的经典案例。

[编辑]:评论中有很多见解、澄清和更正,所以也请阅读!谢谢你们的帮助,伙计们。

于 2008-11-04T09:20:16.630 回答
13

unwind最初所说的大部分是正确的——除了它不限于多线程(此外,用锁保护全局数据使其线程安全——但不一定是可重入的)。[编辑]他现在已经修复了他的帖子以解决这个问题:-)

作为递归的结果,一个函数也可以在同一个线程上重新进入——直接或间接地(即,函数a调用函数b,函数c调用函数a,函数c调用函数a)。

当然,如果您在多个线程可能调用它的基础上防止重入,那么您也适用于递归情况。然而,反过来就不是这样了。

于 2008-11-04T09:29:44.380 回答
12

当在先前的调用返回之前调用函数时,会发生函数的“重新进入”。发生这种情况的主要原因有三个:递归(函数调用自身)、多线程和中断。递归通常更容易,因为很明显该函数将被重新输入。多线程和中断更棘手,因为重入将是异步的。如其他答案所述,在大多数情况下,该函数不应修改全局数据(读取全局数据是可以的,如果作为关键部分保护,一些写作之王是可以的)。

于 2008-11-04T10:33:05.657 回答
3

就这个:

  • 一个可重入函数可以由多个线程同时调用,前提是函数的每次调用都引用唯一的数据。

  • 当每个调用引用共享数据时,多个线程可以同时调用线程安全函数。所有对共享数据的访问都是序列化的。

无耻地从 Qt 手册中窃取。但这是一个简短的定义。基本上,不可重入函数也不是recursion-safe.

现在,什么是recursive函数?这是一种函数的定义。递归函数是根据自身定义的。他们减少输入,打电话给自己,直到可以找出一个基本案例而无需再次打电话给自己。

所以我们有两件事。

  • 递归函数是一种定义。
  • 可重入函数是保证多个线程可以调用它们的函数,前提是每次访问唯一数据时。

现在,上面的多线程工具仅用于同时激活函数的多个目的。但是,如果您有一个递归函数,那么您可以同时多次激活该函数。因此,大多数递归函数也必须是可重入的。

于 2008-11-24T16:57:36.210 回答
2

可重入函数是保证在多线程环境下可以正常工作的函数。意味着当函数被一个线程访问时,另一个线程可以调用它......意味着每个线程都有单独的执行堆栈和处理......所以函数不应包含任何可能损害或干扰执行的静态或共享变量......

可以由线程调用的平均函数,同时从另一个线程安全地运行......并且正确......希望我回答正确......

当然,rem 可重入函数与递归函数不同.... 完全不同的概念.... 可重入函数是保证在多线程环境下可以正常工作的函数。意味着当函数被一个线程访问时,另一个线程可以调用它......意味着每个线程都有单独的执行堆栈和处理......所以函数不应包含任何可能损害或干扰执行的静态或共享变量......

意味着它不应该包含任何静态或共享变量....

可以由线程调用的平均函数,同时从另一个线程安全地运行......并且正确......希望我回答正确......

当然,rem 可重入函数与递归函数不同......完全不同的概念......

阅读更多:http ://wiki.answers.com/Q/What_is_a_reentrant_function#ixzz1wut38jLF 维基:http ://en.wikipedia.org/wiki/Reentrancy_%28computing%29

于 2012-06-05T11:16:32.040 回答
-2

所有可重入代码都是递归,但并非所有递归都是可重入的。递归的示例是任何直接或间接调用自身的函数。可重入的示例是中断处理程序例程。

于 2010-12-03T04:36:39.883 回答
-2

所有递归代码都是可重入的……但并非所有可重入代码都是递归的。

于 2012-01-27T19:12:57.287 回答