大多数时候,再入的定义引用自维基百科:
A computer program or routine is
described as reentrant if it can be
safely called again before its
previous invocation has been completed
(i.e it can be safely executed
concurrently). To be reentrant, a
computer program or routine:
Must hold no static (or global)
non-constant data.
Must not return the address to
static (or global) non-constant
data.
Must work only on the data provided
to it by the caller.
Must not rely on locks to singleton
resources.
Must not modify its own code (unless
executing in its own unique thread
storage)
Must not call non-reentrant computer
programs or routines.
如何定义安全?
如果一个程序可以安全地并发执行,那么它是否总是意味着它是可重入的?
在检查代码的重入功能时,我应该记住的这六点之间的共同点究竟是什么?
同时,
是否所有递归函数都是可重入的?
是否所有线程安全的函数都是可重入的?
是否所有递归和线程安全的函数都是可重入的?
在写这个问题的时候,我想到了一件事:
像重入和线程安全这样的术语是绝对的吗?也就是说,它们有固定的具体定义吗?因为,如果不是,这个问题就没有多大意义。
不可重入函数意味着将有一个静态上下文,由函数维护。第一次进入时,将为您创建新的上下文。下一个输入,你不需要发送更多的参数,为了方便标记分析。例如c中的strtok,如果你没有清楚上下文,可能会有一些错误。
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
on the contrary of non-reentrant, reentrant function means calling function in anytime will get the same result without side effect. because there is none of context.
in the view of thread safe, it just means there is only one modification for public variable in current time, in current process. so you should add lock guard to ensure just one change for public field in one time.
so thread safety and reentrant are two different things in different views.reentrant function safety says you should clear context before next time for context analyze. thread safety says you should keep visit public field order.
所列出的要点中的“共同主线”(双关语!?)是函数不能做任何会影响对同一函数的任何递归或并发调用的行为的事情。
比如静态数据就是个问题因为它属于所有线程;如果一个调用修改了一个静态变量,那么所有线程都会使用修改后的数据,从而影响它们的行为。自修改代码(虽然很少遇到,在某些情况下被阻止)将是一个问题,因为尽管有多个线程,但只有一个代码副本;代码也是基本的静态数据。
从本质上讲,要实现可重入,每个线程必须能够使用函数,就像它是唯一的用户一样,如果一个线程可以以不确定的方式影响另一个线程的行为,则情况就不是这样了。这主要涉及到每个线程都有函数所处理的独立数据或常量数据。
综上所述,第(1)点不一定是正确的;例如,您可以合理地设计使用静态变量来保留递归计数,以防止过度递归或分析算法。
A thread-safe function need not be reentrant; it may achieve thread safety by specifically preventing reentrancy with a lock, and point (6) says that such a function is not reentrant. Regarding point (6), a function that calls a thread-safe function that locks is not safe for use in recursion (it will dead-lock), and is therefore not said to be reentrant, though it may nonetheless safe for concurrency, and would still be re-entrant in the sense that multiple threads can have their program-counters in such a function simultaneously (just not with the locked region). May be this helps to distinguish thread-safety from reentarncy (or maybe adds to your confusion!).