这两个不是一个意思。但有时候有重叠。在多线程情况下,县城安全是可重入的必要条件。但是线程安全不一定能保证可重入。
比如单线程程序的函数,当然不存在线程安全问题,但不一定就是可重入的。比较经典的例子是最早DOS的TSR程序,由于用了同一堆栈指针,函数重入的时候会把栈写坏。还有比如Fortran一类的不支持递归的语言,由于变量是静态地址,无法可重入。
总之对于可重入函数,里面不能有大家同时可以用的公共资源。比如下面程序:
int 阶乘(int
n)
{
static int i = 1;
if (n)
i = i * 阶乘(n-1);
else
i = 0;
return i;
}
即使单线程也会出问题。
Chiyer(星羽) 兄给出了全局变量的线程安全处理示例:这种情况说明的是多个线程实例并发操作同一存储区域的数据的问题,就应用角度来说,本身就是不可重入的。
可重入的定义请翻阅相关课本。
微软早期的OS中的多线程是不可重入的,比如下面这个线程函数并发 3
次
void fun(void*p)
{
int i = 0;
++i;
}
最后得到的结果可能是
1,2,3 中任何结果。可能当时微软的多线程函数中的局部变量不是采用的堆栈,而是采用的共享存储。当时要做到线程函数中的局部变量相互独立(即保证线程安全,也可
以说保证线程函数可重入----但可重入表现在计算科学各方面,不只是线程),Borland
提供了 C++
多线程库。
说一个不可重入,但是线程安全的例子,帮助大家理解
funca()
{
lock(a);
......//interrupt by signal and call funca(), so dead lock
unlock(a);
}
int main()
{
signal(sig, funca);
funca();
}