thread_local变量是C++ 11新引入的一种存储类型。它会影响变量的存储周期(Storage duration),被thread_local声明的变量在行为上非常像静态变量,只不过多了线程属性。
在同一个线程中,一个线程局部存储对象只会初始化一次,即使在某个函数中被多次调用,这一点和单线程中的静态对象非常相似。对象的存储在线程开始时分配,相对应的,对象的销毁也只会发生一次,通常发生在线程退出的时刻,接下看几个例子。
thread_local 只对声明于命名空间作用域的对象、声明于块作用域的对象以及静态数据成员允许。它指示对象拥有线程存储期。它能与 static 或 extern 结合,以分别指定内部或外部链接(除了静态数据成员始终拥有外部链接),但附加的 static 不影响存储期。
#include
#include
thread_local int g_nx = 1;
void thread_func(const std::string& thread_name) {
for (int i = 0; i < 50; i++) {
printf("thread[%s]:g_nx = %d\n", thread_name.c_str(),g_nx);
g_nx++;
}
}
int main() {
std::thread t1(thread_func, "t1");
std::thread t2(thread_func, "t2");
t1.join();
t2.join();
system("pause");
return 0;
}
结果:

从结果可以看出,每个线程各自拷贝了一份数据。

修改线程函数如下:
void thread_func(const std::string& thread_name) {
for (int i = 0; i < 50; i++)
{
thread_local int g_nx = 1;
printf("thread[%s]:g_nx = %d\n", thread_name.c_str(),g_nx);
g_nx++;
}
}
结果和“一、全局变量”相同,g_nx只在线程创建的时候执行了一次。那如果换成static,会有什么反应呢?
void thread_func(const std::string& thread_name) {
for (int i = 0; i < 50; i++)
{
std::lock_guard<std::mutex> lc(mutexx);
static int g_nx = 1;
printf("thread[%s]:g_nx = %d\n", thread_name.c_str(),g_nx);
g_nx++;
}
}

class A {
public:
A() {
std::cout << "构造函数\n";
}
~A() {
std::cout << "析构函数\n";
}
int get_value()
{
return counter++;
}
private:
int counter = 0;
};
void thread_func(const std::string& thread_name) {
for (int i = 0; i < 3; ++i)
{
thread_local std::shared_ptr<A> spA(new A());
printf("thread[%s]:a.counter = %d\n", thread_name.c_str(), spA->get_value());
}
return;
}
int main()
{
{
std::thread t1(thread_func, "t1");
std::thread t2(thread_func, "t2");
t1.join();
t2.join();
}
system("pause");
return 0;
}
结果:

thread_local 作为类成员变量时必须是 static 的!
class A {
public:
A() {
std::cout << "构造函数\n";
}
~A() {
std::cout << "析构函数\n";
}
static int inline m_sN = 15;
static int inline thread_local m_tlN = 15;
};
void thread_func(const std::string& thread_name)
{
A a;
for (int i = 0; i < 3; ++i)
{
a.m_sN--;
a.m_tlN--;
printf("thread[%s]:m_sN = %d,m_tlN =%d \n", thread_name.c_str(),a.m_sN,a.m_tlN);
}
return;
}
int main()
{
{
std::thread t1(thread_func, "t1");
std::thread t2(thread_func, "t2");
t1.join();
t2.join();
}
system("pause");
return 0;
}
结果:
