线程局部存储(TLS)
一个进程下的多个线程共享代码段、数据段、打开的文件描述符表等绝大部分信息,因为它们都运行在同一个内存地址空间下(即处于同一个虚拟地址下,使得可以通过相同的逻辑地址来找到存储于内存或硬盘中的物理地址。)
常见的线程结构图如下图所示,即上面提到的共享的一些资源。
但线程也会拥有一些属于自己的私有资源。如上图所提到的寄存器,以及栈。
寄存器即为每个线程运行时需要一些寄存器来保存一些局部变量信息,这些寄存器是线程私有的,如程序计数器寄存器,即控制程序指令执行顺序的寄存器。
栈区即为线程运行时,执行进程所分配给它的一些功能,即类似于函数的执行,它会像函数执行一样,拥有一个保存函数运行时信息的栈区。(私有不代表线程间不可以相互访问,若当前线程拥有其他线程栈的地址则仍可进行访问)
除此之外,线程还拥有TLS,即线程局部存储,来使得一个全局变量变为线程私有的。
**TLS:**每个线程都会拥有这个变量的副本,任何线程对该变量的修改都不会影响其他线程中该变量的副本。
以Windows系统为例,每个线程都会在堆中有一个.tls段,用来存放线程运行时的私有数据,彼此间相互独立。
对于我们,若想使用TLS,则需要加入对应的关键字。
Linux(gcc):__thread
__thread int i;
Windows(MSVC) : __declspec(thread)
__declspec( thread ) int i = 1;
NanoLog日志系统便是通过__thread关键字来使得不同线程下拥有不同的日志存储区,进而使得减少了不同线程在向同一日志缓冲区写日志数据时加锁解锁所带来的时间开销。