C++中能否将thread_local变量设为全局并跨翻译单元访问?
问题解答
1 如何在fun()中访问thread_local变量
你的var定义在main.cpp这一个翻译单元中,默认其他翻译单元无法感知到这个变量。thread_local是存储类说明符,本身不会修改变量的链接属性,所以跨翻译单元访问的逻辑和普通全局变量一致,补充外部声明即可。下面提供两种实现方案:
方案1:直接通过extern声明暴露变量
- 第一步修改
fun.h,添加变量的外部声明:
// fun.h // 声明var是外部定义的thread_local全局变量 extern thread_local int var; int fun();
- 第二步修改
fun.cpp,直接访问变量即可:
// fun.cpp #include "fun.h" int fun() { // 这里访问的就是当前调用线程的私有var副本 var += 10; return var; }
main.cpp的代码无需修改,其中thread_local int var = 0;是变量的定义,整个程序只能有一处该定义。
方案2:封装存取函数(更推荐,模块化程度更高)
如果不想把变量直接暴露给所有引用头文件的单元,可以封装存取函数,避免变量被意外修改:
- 第一步修改
fun.h,声明存取函数:
// fun.h int& get_thread_var(); void set_thread_var(int val); int fun();
- 第二步在
main.cpp中实现存取函数:
// main.cpp #include "fun.h" thread_local int var = 0; int& get_thread_var() { return var; } void set_thread_var(int val) { var = val; } int main() { var = 1; fun(); return 0; }
- 第三步在
fun.cpp中通过存取函数访问变量:
// fun.cpp #include "fun.h" int fun() { int current = get_thread_var(); current += 10; set_thread_var(current); return current; }
2 全局变量共享和thread_local私有是否矛盾
二者完全不矛盾,描述的是不同维度的属性:
- 我们常说的「普通全局变量进程内共享」,指的是静态存储期变量的实例分配规则:整个进程生命周期内只有一份实例,所有线程访问的都是同一个内存地址的变量。
thread_local修改的是变量的存储期,会把变量的实例分配规则改成每个线程独立拥有一份,生命周期和线程绑定:线程启动时初始化本线程的副本,线程退出时销毁副本。- 加了
thread_local的全局变量,只是存储期发生了变化,它的作用域、链接属性和普通全局变量完全一致:你依然可以通过extern声明跨翻译单元访问,访问到的永远是当前执行线程的私有副本,不会影响其他线程的同名变量值。
内容的提问来源于stack exchange,提问作者sauce
相关产品推荐
相关产品推荐

