- 什么是thread_local
thread_local用来修饰变量,此变量具有线程周期,就是说变量的生命周期和所属线程的生命周期一样。C++11新增加特性 - 适合哪些使用场景
线程独有的内存空间,可以用thread_local来修饰。程序中每个线程需要一个专属的变量空间,栈虽然是线程独有,可退出函数之后,存在栈中的局部变量会自动释放。而thread_local变量不会。 - 怎么用,上代码
#include <iostream>
#include <thread>
using namespace std;
// g++ -std=c++11 -lpthread ./demo.cpp -o demo
thread_local int g_n = 1;
void f() {
g_n++;
std::cout << "id=" << std::this_thread::get_id() << ", n=" << g_n
<< std::endl;
}
void foo() {
thread_local int i = 0;
std::cout << "id=" << std::this_thread::get_id() << ", i=" << i
<< std::endl;
i++;
}
void f2() {
foo();
foo();
}
int main() {
g_n++; //修改操作并不影响g_n在线程t2和t3中的初始值(值为1)
f();
std::thread t1(f);
std::thread t2(f);
t1.join();
t2.join();
f2();
std::thread t4(f2);
std::thread t5(f2);
t4.join();
t5.join();
return 0;
}
每个线程中的thread_local int g_n是不一样的
thread_local int i = 0; 也是不一样的。 在每个线程中都有自己独立的空间。
输出
id=140325618280320, n=3 //主线程
id=140325601474304, n=2 //t1
id=140325593081600, n=2 //t2
id=140325618280320, i=0 //主线程
id=140325618280320, i=1 //主线程
id=140325593081600, i=0 //t4
id=140325593081600, i=1 //t4
id=140325601474304, i=0 //t5
id=140325601474304, i=1 //t5
- 使用起来挺简单的,下面讲下它的原理
thread_local 来源于 boost的thread_specific_ptr
thread_specific_ptr代表了一个全局的变量,而在每个线程中都各自new一个线程本地的对象交给它进行管理,这样,各个线程就可以各自独立地访问这个全局变量的本地存储版本,线程之间就不会因为访问同一全局对象而引起资源竞争导致性能下降。而线程结束时,这个资源会被自动释放。
代码参考
https://blog.csdn.net/zzhongcy/article/details/91372329
https://blog.csdn.net/u013390476/article/details/52129607