带着问题去学习
一种计算机编程方法,使用线程本地静态或全局的内存。
编译之后存放在TLS section,如果没有初始值,则在.tbss;如果有初始值,则在.tdata;
#include <stdio.h>
#include <thread>
thread_local int hello = 3;
int main(int argc, char** argv){
printf("hello:%d\n",hello);
return 0;
}
使用readelf -s 查看hello符号的位置(首先将上述代码编译成main二进制)
readelf -s main | grep -E ‘hello|Num’
输出:
Num: Value Size Type Bind Vis Ndx Name
Num: Value Size Type Bind Vis Ndx Name
58: 0000000000000000 4 TLS GLOBAL DEFAULT 21 hello
Ndx表示符号所属的段,使用readelf -S 查看21 是什么段
readelf -S main | grep -A 1 -E ‘[21|Name’
输出
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
--
[21] .tdata PROGBITS 0000000000003db4 00002db4
0000000000000004 0000000000000000 WAT 0 0 4
所以thread_local变量hello的符号类型为TLS,全局作用域,位于.tdata段中。
ps: 当thread_local变量没有初始化时,位于.tbss段(和全局变量类似,初始化的全局变量位于.data段,未初始化的全局变量位于.bss段), 感兴趣的可以将thread_local int hello = 3;改为thread_local int hello;然后再按照上面步骤进行查看。
编译之后存放在什么段?
答案:初始化的thread_local变量编译过后位于.tdata段,未初始化的位于.tbss段。
线程使用变量时,从相应数据段中复制数据,然后存放在thread local storage区域。