线程安全问题都是由全局变量和静态变量引起的
可重入函数是线程安全函数的子集
可重入的要求:不使用、不返回任何非常量的全局或者静态变量,也不调用任何不可重入函数。它可以被中断,意味着它除了使用自己栈上的变量不依赖于任何环境(包括static),这样的函数就是purecode(纯代码)可重入。可以允许有多个函数的副本在同时运行,因为它们使用的是分离的栈,不会互相干扰。但是对于不可重入的函数,由于使用了一些系统资源比如全局变量,中断向量表等,如果它被中断的话,可能会出现问题,这类函数是不能运行在多任务环境下的。
线程安全的要求是:在多个线程中同时调用一个函数时,能够得到预期的结果,多个线程的切换不会导致该接口的执行结果产生二义性。线程安全函数在执行时多个线程可以互相影响,即使输入一样输出也可能因为中途的其他线程的行为而不一样。所以函数的返回值不具有可再现性。所以也就不一定是可重入函数。
1、如果一个函数的实现使用了全局或者静态变量,那么这个函数既不是可重入的也不是线程安全的。
2、但是针对1中的情况,如果放宽条件,这个函数仍然用到了全局或者静态变量,但是在访问这些变量的时候,通过加锁来保证互斥访问,那么这个函数就可以变成线程安全的函数。但他此时仍然是不可重入的,因为通常加锁是针对不同线程的访问,对同一线程可能出现问题。
3、所以如果把函数中的全局或者静态变量都去掉,并保证在该函数中不会调用不可重入函数,那么这个函数就可以做到既是线程安全的,也是可重入的。
所以:可重入函数一般都是线程安全的,线程安全的不一定是可重入的。可重入函数要求更高,线程安全可以用锁,可重入不行(否则死锁)