C中的可重入函数和递归函数有什么区别?
在 CI 中知道递归函数,但我听说过可重入函数。
那是什么? 它们之间有什么区别?
In C I know about the recursive function but I heard about the re-entrant function.
What is that? And whats the difference between them?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
当您理解该术语的含义时,就更容易记住。
术语“可重入”意味着在函数已经执行时“重新进入”是安全的,通常是在并发环境中。
换句话说,当两个任务可以同时执行该函数且互不干扰时,则该函数是可重入的。
当一个任务的执行对另一任务的影响有影响时,函数不可重入。 这通常是使用全局状态或数据时的情况。 仅使用局部变量和参数的函数通常是可重入的。
It's easier to remember when you understand what the term means.
The term "re-entrant" means that it is safe to "re-enter" the function while it is already executed, typically in a concurrent environment.
In other words, when two tasks can execute the function at the same time without interfering with each other, then the function is re-entrant.
A function is not re-entrant when the execution by one task has an impact on the influence of another task. This typically is the case when a global state or data is used. A function that uses only local variables and arguments is typically re-entrant.
如果一个函数支持多个执行线程同时“通过”它,则该函数是可重入的。 这可能是由于实际的多线程所致,我在下面使用了这种情况,或者由于其他海报指出的其他原因。 多线程是第一个想到的,而且可能也是最容易理解的,所以我专注于这种情况。
这意味着该函数不能使用静态“全局”数据,因为该数据将被两个(或更多)线程并行访问,通常会造成严重破坏。 可重入函数通常有一个显式参数来保存任何特定于调用的状态,而不是静态存储它。
strtok()
是 C 标准库中众所周知的不可重入函数的经典案例。[编辑]:评论中有很多见解、澄清和更正,所以也请阅读这些! 谢谢各位的帮助。
A function is re-entrant if it supports having multiple threads of execution "going through" it at the same time. This might be due to actual multi-threading, and I use this case below, or due to other things as pointed out by other posters. Multi-threading was the first that came to mind, and is perhaps also the easiest to understand, so I focused on that case.
This means that the function cannot use static "global" data, since that data would then be accessed by two (or more) threads in parallel, often breaking horribly. A re-entrant function often has an explicit argument to hold any call-specific state, rather than storing it statically.
strtok()
is a classic case of a function in the C standard library that is well-known not to be re-entrant.[Edit]: There are a bunch of insights, clarifications and corrections in the comments, so please read those as well! Thanks for the help, folks.
unwind 最初所说的基本上是正确的 - 除了它不限于多线程(而且,用锁保护全局数据使其线程安全 - 但不一定重新 -参赛者)。 [编辑] 他现在修复了他的帖子以解决这个问题:-)
由于递归的结果,函数也可能在同一线程上重新输入 - 直接或间接(即,函数 a 调用函数 b,函数 b 调用函数 c,其中调用函数a)。
当然,如果您基于多个线程可能调用它来防止重入,那么您也可以应对递归情况。 然而,反之则不然。
What unwind originally said is mostly correct - except that it is not limited to multi-threading (also, protecting global data with locks makes it thread safe - but not necessarily re-entrant). [Edit] He's fixed his post to account for this now :-)
A function may also be re-entered on the same thread as a result of recursion - either directly or indirectly (ie, function a calls function b which calls function c which calls function a).
Of course if you have protected against re-entrancy on the basis that multiple threads may call it then you are covered for the recursive cases too. That's not true the other way around, however.
当函数在前一个调用返回之前被调用时,就会发生函数的“重新进入”。 发生这种情况的主要原因有三个:递归(函数调用自身)、多线程和中断。 递归通常更容易,因为很明显函数将被重新输入。 多线程和中断更加棘手,因为重新进入将是异步的。 正如其他答案中所述,在大多数情况下,该函数不应修改全局数据(读取全局数据是可以的,如果将其保护为关键部分,则某些写入国王是可以的)。
"Re-entrance" of a function occurs when it is called before a previous invocation has returned. There are three main reasons for that to occur: recursion (the function calls itself), multi-threading and interruption. Recursion is normally easier, since it is clear that the function will be re-entered. Multi-threading and interruption are more tricky, as the re-entrance will be asynchronous. As stated in other answers, in most cases the function should not modify global data (reading global data is ok, some kings of writing is ok if protected as critical sections).
如下:
可重入函数可以由多个线程同时调用,前提是该函数的每次调用都引用唯一的数据。
可重入函数可以由
当每个调用引用共享数据时,线程安全函数可以由多个线程同时调用。 对共享数据的所有访问都是序列化的。
无耻地从 Qt 手册中窃取。 但这是一个简短的定义。 基本上,不可重入函数也不是递归安全的。
现在,什么是递归函数? 这是函数的一种定义。 递归函数是根据其自身定义的。 他们减少输入,调用自己,直到可以弄清楚基本情况,而无需再次调用自己。
所以我们有两件事。
现在,上面的多线程工具仅用于同时多次激活该功能的目的。 但是,如果您有一个递归函数,那么您还可以同时多次激活该函数。 因此,大多数递归函数也必须是可重入的。
Here is it:
A reentrant function can be called simultaneously by multiple threads provided that each invocation of the function references unique data.
A thread-safe function can be called simultaneously by multiple threads when each invocation references shared data. All access to the shared data is serialized.
Shamelessly stolen from the Qt manual. But it's a short and concise definition. Basicially, a non-reentrant function is also not
recursion-safe
.Now, what is a
recursive
function? It's a kind of definition of a function. Recursive function are defined in terms of themself. They reduce input, call theirself, until a basic case can be figured out without the need of calling theirself again.So we have two things.
Now, the multiple-threads vehicle above serves only the purpose of having multiple activations of the function at the same time. But if you have a recursive function, you also have multiple activations of that functions at the same time. Most recursive functions therefor must be re-entrant too.
可重入函数是保证在多线程环境下能够正常工作的函数。
意味着虽然函数由一个线程访问,但另一个线程可以调用它...意味着每个函数都有单独的执行堆栈和处理...
因此函数不应包含任何可能损害或干扰执行的静态或共享变量。
可以由线程调用的意思是函数,同时从另一个线程安全地运行......并且正确......希望我已经回答了正确的事情......
当然,重入函数与递归函数不同......完全不同的概念......
可重入函数是保证在多线程环境下能够正常工作的函数。
意味着虽然函数由一个线程访问,但另一个线程可以调用它...意味着每个函数都有单独的执行堆栈和处理...
因此函数不应包含任何可能损害或干扰执行的静态或共享变量..
意味着它不应包含任何静态或共享变量....
意味着可以由线程调用的函数,同时从另一个线程安全地运行.. ....正确地...希望我已经回答了正确的问题....
当然,重入函数与递归函数不同...完全不同的概念...
阅读更多: http://wiki.answers.com/Q/What_is_a_reentrant_function#ixzz1wut38jLF
维基百科:http://en.wikipedia.org/wiki/Reentrancy_%28computing%29
A Re entrant function is a function which guaranteed that which can be work well under multi threaded environment.
mean while function is access by one thread, another thread can call it... mean there is separate execution stack and handling for each...
So function should not contain any static or shared variable which can harm or disturb the execution..
Mean function which can be called by thread, while running from another thread safely...... and properly.... hope I have answered the correct thing....
And of course rem that re-entrant function is not same as recursive function.... totally different concept....
A Re entrant function is a function which guaranteed that which can be work well under multi threaded environment.
mean while function is access by one thread, another thread can call it... mean there is separate execution stack and handling for each...
So function should not contain any static or shared variable which can harm or disturb the execution..
mean it should not contain any static or shared variable....
Mean function which can be called by thread, while running from another thread safely...... and properly.... hope I have answered the correct thing....
And of course rem that re-entrant function is not same as recursive function.... totally different concept....
Read more: http://wiki.answers.com/Q/What_is_a_reentrant_function#ixzz1wut38jLF
Wiki : http://en.wikipedia.org/wiki/Reentrancy_%28computing%29
为了帮助您直观地了解不可重入函数的示例:“打开冰箱”、“将大象放入冰箱”、“关闭冰箱”。
另一个例子,不可重入但递归,“打开礼品盒”,“如果你看到里面有盒子,则打开礼品盒[RECURSIVE CALL],否则拿走礼物并享受”。
可重入的例子就像“买新冰箱,打开冰箱,把大象放进去,关闭冰箱”——它是可重入的,因为我们每次都有新冰箱。
To help you with intuition, example of a non-reentrant function: "open fridge", "put an elephant into fridge", "close fridge".
And another example, non-reentrant but recursive, "open gift box", "if you see box inside, open gift box [RECURSIVE CALL], otherwise take the gift and enjoy".
Examples of reentrant would be like "buy new fridge, open fridge, put elephant into it, close fridge" - it is reentrant because we have new fridge each time.
所有可重入代码都是递归,但并非所有递归都是可重入。 递归的例子是任何直接或间接调用自身的函数。 可重入的示例是中断处理程序例程。
All re-entrant code is a recursion but not all recursion is a re-entrant. Example for recursion is, any function, which calls itself directly or indirectly. Example for re-entant is, interrupt handler routines.
所有递归代码都是可重入的...但并非所有可重入代码都是递归的。
All recursive code are re-entrant...but not all re-entrant code recursive.