0x00 线程局部存储
线程局部存储,它实现了线程内局部变量的存储访问。该技术下定义的变量能被同一个线程内部的各个函数调用,同时杜绝了其他线程对这些变量的访问。
(线程局部存储设计Windows进程和线程,所以在研究TLS之前,要先了解windows进程和线程相关的内容。)
作用:TLS解决了多线程程序设计中同步变量问题。
实现:解决同步变量的问题,也就是几个线程共用一个变量X,TLS的解决方法是,每个线程,开辟一个空间当对A线程进行操作的时候,操作的是A线程的X,当对B线程进行操作的时候,是对B线程的X进行操作。
具体实现就是在进程中建立一个全局表,通过现成的ID去查询相应的数据结构,因为每个线程的ID是不一样的,所以查到的数据也自然不一样了。
实现的方法有俩种:
- 动态线程局部存储技术
- 静态线程局部存储技术
0x01 动态线程局部存储技术
主要通过四个函数TlsAlloc( )、TlsSetValue( )、TlsGetValue( )、TlsFree( )来实现,同时生成的PE文件中没有.tls表。
TlsAlloc( ):分配线程局部存储空间/索引,该进程任何线程都可以通过该索引来存储和检索线程中的值。
TlsFree( ): 释放线程局部存储空间/索引。
TlsGetValue( ): 获得线程局部存储空间里面的值,按索引取值。
TlsSetValue( ): 设置线程局部存储空间的值,按索引存储。
如下图所示,线程1对进程索引3操作,操作的是线程1的内容;线程2对进程的索引3操作,操作的也只是线程2的内容。
测试用例:
有俩个线程对同一个变量进行操作,发现他们互不影响,并且运行到最后,变量__Number还是最初分配的1,没有被线程改变。
附上代码:
#include"TLSDynamic.h"
/*
动态tls其实就是为每个线程创建一个与其关联的内存块,这个内存块可以当数组使用TlsAlloc可以分配一个没有用过的索引给你,让你在里面写入东西
*/
DWORD WINAPI ThreadProcedure(LPVOID parameter);
DWORD __Number = 0;//动态使用(存放索引)
int _tmain(int argc, TCHAR