C中的重入函数和递归函数有什么区别?

Man*_*bts 21 language-agnostic reentrancy

在CI中了解递归函数,但我听说了重入函数.

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

小智 23

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

术语"可重入"意味着在功能已经执行时" 重新进入 "该功能是安全的,通常是在并发环境中.

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

  • “...通常在并发环境中。” 这是误导。可重入和线程安全不是一回事:http://stackoverflow.com/questions/856823/threadsafe-vs-re-entrant (2认同)

unw*_*ind 16

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

这意味着该函数不能使用静态"全局"数据,因为这些数据将由两个(或多个)并行线程访问,通常会破坏性.重入函数通常有一个显式参数来保存任何特定于调用的状态,而不是静态存储它.

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

[编辑]:评论中有一堆见解,澄清和更正,所以请阅读这些内容!伙计们,感谢您的帮助.

  • 是的,-1.重入并不意味着并发安全. (4认同)
  • 线程本地存储仅修复由于多线程而导致的重新进入,而不是由于递归而重新进入. (3认同)
  • 重入不仅限于并发系统(-1) (2认同)
  • -1.不需要并发.考虑一个修改共享缓冲区的函数(在同一个线程中运行,但不知何故直接或间接地再次调用自身). (2认同)

phi*_*red 10

什么开卷原来说的是正确的大多是-除了它不限于多线程(也,保护全球数据与锁使得线程安全的-但并不一定是重入).[编辑]他现在修改了他的帖子以解释这个问题:-)

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

当然,如果您在多线程可以调用它的基础上防止重入,那么您也可以处理递归情况.然而,反之亦然.

  • 如果您使用线程本地存储方法来解决由于多线程导致的重新进入,那么由于递归情况,它将无法修复重新进入. (2认同)

小智 10

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

  • @Daniel Quadros:我希望我能更多地投票.一个函数,它使用静态数据,但在调用可能调用它的任何函数(然后在之后恢复它)时将其备份到伪栈是递归安全但不是中断安全的.使用静态数据但在输入时将其复制到伪堆栈并在退出时恢复它的函数将是中断安全的但不是可重入的.可重入函数根本无法假装静态数据是本地的. (2认同)