c++关键字之thread_local
是 C++ 中用于声明线程本地存储的存储期说明符。每个线程都拥有变量的独立副本,不同线程对变量的修改不会相互影响。可用于变量、类的静态成员变量和动态分配的对象,适用于需要线程隔离的变量存储场景。使用时,要注意其性能开销、初始化和析构函数的行为,确保在需要线程隔离的情况下正确使用,避免不必要的资源浪费和内存泄漏。以下是一个更复杂的i < 5;t2.join();return 0;在这个示例中,每个线
·

以下是对 thread_local 的详细解释:
1. 基本概念
thread_local是 C++11 引入的存储期说明符,用于声明线程本地存储(Thread Local Storage,TLS)的变量。线程本地存储的变量具有线程作用域,每个线程都有自己的变量副本,线程之间互不干扰。
2. 语法
thread_local int thread_local_var = 0;
class MyClass {
thread_local static int thread_local_static_var;
};
thread_local MyClass::thread_local_static_var = 0;
3. 示例代码
#include <iostream>
#include <thread>
thread_local int thread_local_var = 0;
void increment() {
++thread_local_var;
std::cout << "Thread local var: " << thread_local_var << std::endl;
}
int main() {
std::thread t1(increment);
std::thread t2(increment);
t1.join();
t2.join();
std::cout << "Main thread local var: " << thread_local_var << std::endl;
return 0;
}
4. 代码解释
- 在上述代码中:
thread_local int thread_local_var = 0;声明了一个线程本地存储的变量。void increment()函数中,每次调用increment函数时,thread_local_var都会自增。由于thread_local_var是线程本地存储的,每个线程都有自己的副本,因此不同线程对thread_local_var的修改不会相互影响。
5. 与其他存储期说明符的区别
-
static:static变量在整个程序的生命周期内存在,并且在函数或类中,其作用域局限于声明它的函数或类,所有调用该函数或使用该类的线程共享这个变量。
-
thread_local:thread_local变量在每个线程的生命周期内存在,每个线程都有自己的副本,并且线程之间不会共享该变量。
6. 类的成员变量
thread_local也可以用于类的静态成员变量,使每个线程都有该类静态成员变量的独立副本。
#include <iostream>
#include <thread>
class MyClass {
public:
thread_local static int thread_local_static_var;
};
thread_local int MyClass::thread_local_static_var = 0;
void incrementClassVar() {
++MyClass::thread_local_static_var;
std::cout << "Class thread local var: " << MyClass::thread_local_static_var << std::endl;
}
int main() {
std::thread t1(incrementClassVar);
std::thread t2(incrementClassVar);
t1.join();
t2.join();
std::cout << "Main thread class thread local var: " << MyClass::thread_local_static_var << std::endl;
return 0;
}
7. 动态分配
thread_local也可以与动态分配的对象一起使用。
#include <iostream>
#include <thread>
thread_local int* thread_local_ptr = nullptr;
void allocate() {
if (thread_local_ptr == nullptr) {
thread_local_ptr = new int(0);
}
++(*thread_local_ptr);
std::cout << "Thread local ptr: " << *thread_local_ptr << std::endl;
}
int main() {
std::thread t1(allocate);
std::thread t2(allocate);
t1.join();
t2.join();
if (thread_local_ptr!= nullptr) {
delete thread_local_ptr;
}
return 0;
}
8. 注意事项
-
性能开销:
- 由于每个线程都需要维护
thread_local变量的副本,可能会带来额外的内存开销,尤其是在使用大量thread_local变量或线程数量较多时。
- 由于每个线程都需要维护
-
初始化:
thread_local变量的初始化在每个线程第一次使用该变量时进行,并且只会初始化一次。
-
析构函数:
thread_local变量的析构函数会在其所在线程结束时调用。
9. 总结
thread_local是 C++ 中用于声明线程本地存储的存储期说明符。- 每个线程都拥有
thread_local变量的独立副本,不同线程对thread_local变量的修改不会相互影响。 - 可用于变量、类的静态成员变量和动态分配的对象,适用于需要线程隔离的变量存储场景。
使用 thread_local 时,要注意其性能开销、初始化和析构函数的行为,确保在需要线程隔离的情况下正确使用,避免不必要的资源浪费和内存泄漏。
以下是一个更复杂的 thread_local 示例,涉及多个线程和不同的操作:
#include <iostream>
#include <thread>
#include <vector>
thread_local std::vector<int> thread_local_vector;
void populateVector() {
for (int i = 0; i < 5; ++i) {
thread_local_vector.push_back(i);
}
for (int val : thread_local_vector) {
std::cout << val << " ";
}
std::cout << std::endl;
}
int main() {
std::thread t1(populateVector);
std::thread t2(populateVector);
t1.join();
t2.join();
return 0;
}
在这个示例中,每个线程都有自己的 thread_local_vector 副本,并且可以独立地向其中添加元素,不会影响其他线程的 thread_local_vector。
thread_local 是多线程编程中一个强大的工具,用于确保线程之间的数据隔离,提高程序的并发安全性和可维护性,但要谨慎使用,充分考虑其性能和资源开销。
更多推荐
所有评论(0)