TLS是一种在多线程时使用的技术,它可以使你的全局变量、静态变量以及局部静态、静态成员变量成为线程独立的变量,即每个线程的TLS变量之间互不影响。例如linux下的全局变量 errno,windows下的GetLastError ,线程A在设置了一个错误信息后,线程B又设置了一个错误信息,前一个线程设置的信息就被覆盖了。解决方法就是将这个全局变量设置为TLS变量,这样在用户看来errno是一个全局变量,实际上它是每个线程独立的。
visual c++声明
__declspec(thread) int number;
linux下声明
__thread int number;
关于一些对TLS过度消耗的分析文章网上有不少,根本原因在于取TLS变量的方法。我们普通的全局变量可以直接通过变量名取到变量地址,而TLS则是通过线程id去一个底层维护的数组中取到地址。大体实现方式如下:
void* __tls_get_addr(size_t m, size_t offset)
{
char* tls_block = dtv[thread_id][m];
return tls_block + offset;
}
正常使用TLS只会带来细微的额外消耗,代码如下:
#include "stdio.h"
#include "math.h"
double tlvar;
//get_value被设置为禁止编译器内联
double get_value() __attribute__ ((noinline));
double get_value()