C++11保证了static局部变量的线程安全
在C++标准草案的6.7:
such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization. If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.
- 第一次执行到变量声明的地方时才进行初始化。
- 初始化过程中发生异常的话视为未完成初始化,下次有代码执行到相同位置时再次初始化。
- 在当前线程执行到需要初始化变量的地方时,如果有其他线程正在初始化该变量,则阻塞当前线程,直到初始化完成为止。
- 如果初始化过程中发生了对初始化的递归调用,则视为未定义行为。
从而,单例模式非常容易实现了:
https://blog.csdn.net/qq_35865125/article/details/88582453
在一些老的c++书中还没有与c++俱进。
Ref:
https://www.cnblogs.com/wangshaowei/p/13498412.html
https://blog.csdn.net/imred/article/details/89069750 -- gcc实现的原理
static变量的构造时间测试
Note1: 函数内部定义的静态变量,并不是在程序一开始统一初始化的,而是第一次执行到该函数时初始化。以前有误解。
Note2: 析构函数在main函数退出后才执行。
#include <iostream>
class staticSafe
{
public:
staticSafe() {
std::cout << "staticSafe() was exed! \n";
}
~staticSafe() {
std::cout << "~staticSafe() was exed! \n";
}
};
void test() {
static staticSafe obj;
}
int main() {
/*Note:如果不掉用该函数,test()函数中的静态成员变量不会被初始化!
之前有误解,以为在程序进入main之间会先将所有的static变量全部初始化.*/
test();
test();
test();//调用三次test函数,其内部的obj只会被实例化一次。
std::cout << "Hi \n";
//析构函数在main函数退出后才执行。
char z = getchar();
return 0;
}