TLS线程局部存储

线程局部存储(TLS)用于在多线程环境中为每个线程提供独立的数据副本,避免了全局变量的同步问题。Windows中TLS有两种实现方式:静态(__declspec(thread))和动态(TlsAlloc等函数)。静态实现通过编译器扩展,动态实现则涉及系统级的TLS管理。静态实现时,编译器会插入额外指令进行TLS寻址,而动态实现通过TLS分配、释放、获取和设置值的函数来操作。
摘要由CSDN通过智能技术生成

多线程程序当中,因为线程之间共享进程的数据,所以在访问全局数据的时候,可能需要加锁互斥访问。但是全局数据的互斥访问只有在多个线程之间协作进行处理的时候,才有必要。但是如果数据在各个线程之间都需要单独的副本,比如说VC CRT库当中的errno变量,我们希望这个变量仅仅由当前线程错误来设置,并且只影响当前线程,那么这种线程之间共享的副本数据该怎么实现呢?

微软提供的一种实现就是TLS(线程局部存储)。TLS有两种实现方法,第一是静态的实现,那就是利用连接器扩展__declspecthread)修饰所定义的变量,这使得数据在各个线程当中都有副本;另一种方法是利用系统提供的函数动态实现。

首先分析静态实现。在《windows核心编程》里面,作者提到每一个TLS的静态支持需要额外的三条指令。利用实验验证下。

#include<stdio.h>

__declspec(thread) int a;

int main()

{

a=0;

printf("%d",a);

return 0;

}

上面是一个很简单的VC环境下面的程序,利用VC的调试功能对他进行反汇编。得到的汇编代码如下所示:

1:    #include<stdio.h>

2:    __declspec(thread) int a;

3:    int main()

4:    {

00401010   push        ebp

00401011   mov         ebp,esp

00401013   sub         esp,40h

00401016   push        ebx

00401017   push        esi

00401018   push        edi

00401019   lea         edi,[ebp-40h]

0040101C   mov        ecx,10h

00401021   mov        eax,0CCCCCCCCh

00401026   rep stos    dword ptr [edi]

5:        a=0;

00401028   mov         eax,[__tls_index (00427e58)]

0040102D   mov         ecx,dword ptr fs:[2Ch]

00401034   mov         edx,dword ptr [ecx+eax*4]

00401037   mov         dword ptr [edx+104h],0

6:        printf("%d",a);

00401041   mov         eax,[__tls_index (00427e58)]

00401046   mov         ecx,dword ptr fs:[2Ch]

0040104D   mov         edx,dword ptr [ecx+eax*4]

00401050   mov         eax,dword ptr [edx+104h]

00401056   push        eax

00401057   push        offset string "%d" (0042201c)

0040105C   call        printf (00401090)

00401061   add         esp,8

<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值