C++11静态变量构造线程安全

在c++11中,static静态类对象在执行构造函数进行初始化的过程是线程安全的。

#include
#include
using namespace std;
class Cnum
{
public:
Cnum()
{
std::cout << “construct start” << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(5)); //构造函数中休眠5s
num++;
std::cout << “construct stop” << std::endl;
}
void Test()
{
std::cout << “id:” << std::this_thread::get_id() << “,num=” << num << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
static int num;
};

int Cnum::num = 0; //初始化静态成员
void func(void* argv)
{
int i = *(int *)argv;
std::cout << i << std::endl; //每个线程启动时,打印线程次序号
static Cnum a; //内部静态成员变量的初始化时线程安全的,只有一个线程能执行初始化,其他线程会在此阻塞
a.Test();
}

void main()
{
for (int i = 0; i < 10; i++) //开启10个线程,模拟并发访问情形
{
std::thread t1(func, (void *)&i);
t1.detach();
}
system("pause ");//暂停一下
}

运行结果:
C++11静态变量构造线程安全
在结果中,可以看到i在循环打印,但"construct start"、"construct stop"都只打印一次,说明当有一个线程进行构造,其他线程再也不会进行构造,且被阻塞等待构造完成,再往下执行,id表明不同线程,num表明构造值进行一次