首页 > 系统相关 >21.2 静态TLS--《Windows核心编程》

21.2 静态TLS--《Windows核心编程》

时间:2022-11-23 11:58:22浏览次数:45  
标签:TLS 变量 21.2 -- 应用程序 DLL 静态 线程

部分笔记来自于:https://blog.csdn.net/Steven_programe_life/article/details/103358251?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-103358251-blog-123158318.pc_relevant_3mothn_strategy_and_data_recovery&spm=1001.2101.3001.4242.1&utm_relevant_index=3

 

静态TLS的使用

静态TLS在代码中使用时非常简单,我们只需写类似如下这一句:

  __declspec(thread) DWORD myTLSData=0;

我们就为本程序中的每一个线程创建了一个独立的DWORD数据。

__declspec(thread)的前缀是Microsoft添加给Visual C++编译器的一个修改符。它告诉编译器,对应的变量应该放入可执行文件或DLL文件中它的自己的节中。__declspec(thread)后面的变量必须声明为函数中(或函数外)的一个全局变量或静态变量。不能声明一个类型为__declspec(thread)的局部变量,你想,因为局部变量总是与特定的线程相联系的,如果再加上这个声明是代表什么意思。

 


 

静态TLS原理

首先,在编译器对程序进行编译时,它会将所有声明的TLS变量放入它们自己的节,这个节的名字是.tls。而后链接程序将来自所有对象模块的所有.tls节组合起来,形成结果的可执行文件或DLL文件中的一个大的完整的.tls节。

然后,为了使含有静态TLS的程序能够运行,操作系统必须参与其操作。当TLS应用程序加载到内存中时,系统要寻找可执行文件中的.tls节,并且动态地分配一个足够大的内存块,以便存放所有的静态TLS变量。应用程序中的代码每次引用其中的一个变量时,就要转换为已分配内存块中包含的一个内存位置。因此,编译器必须生成一些辅助代码来引用该静态TLS变量,这将使你的应用程序变得比较大而且运行的速度比较慢。在x86 CPU上,将为每次引用的静态TLS变量生成3个辅助机器指令。如果在进程中创建了另一个线程,那么系统就要将它捕获并且自动分配另一个内存块,以便存放新线程的静态TLS变量。新线程只拥有对它自己的静态TLS变量的访问权,不能访问属于其他线程的TLS变量。

以上是包含静态TLS变量的可执行文件如何运行的情况。我们再来看看DLL的情况:

a、隐式链接包含静态TLS变量的DLL

如果应用程序使用了静态TLS变量,并且隐式链接包含静态TLS变量的DLL时,当系统加载该应用程序时,它首先要确定应用程序的.tls节的大小,并将这个值与应用程序链接的DLL中的所有.tls节的大小相加。当在你的进程中创建线程时,系统自动分配足够大的内存块来存放所有应用程序声明的和所有隐含链接的DLL包含的TLS变量。

b、显式链接包含静态TLS变量的DLL

考虑一下,当我们的应用程序通过调用LoadLibrary,以便显式链接到包含静态TLS变量的DLL时,会发生什么情况呢?系统必须查看该进程中已经存在的所有线程,并扩大它们的TLS内存块,以便适应新DLL对内存的需求。另外,如果调用FreeLibrary来释放包含静态TLS变量的DLL,那么与进程中的每个线程相关的的TLS内存块又都应该被压缩。

对于操作系统来说,这样的管理任务太重了。所以,虽然系统允许包含静态TLS变量的库在运行期进行显式加载,但是其包含TLS数据却没有进行相应的初始化。如果试图访问这些数据,就可能导致访问违规!

所以,请记住:如果某个DLL包含静态TLS数据,请不要对这个DLL采用显式链接的方式,否则可能会出错!

 

标签:TLS,变量,21.2,--,应用程序,DLL,静态,线程
From: https://www.cnblogs.com/renleiguanchashi/p/16917800.html

相关文章

  • 高德地图POI分类和城市列表
    高德地图POI分类和城市列表高德地图对POI一共有三级分类(大类、中类、小类),其中一级分类有23个,二级分类有267个,三级分类有869个。分类文档的下载网址参见:https://lbs.amap......
  • wpf 子页面调用父窗口方法
     参考:http://www.360doc.com/content/17/1113/11/24811_703389993.shtml//1)子页面后台定义委托(namespace下class外)//定义委托internaldelegatevoidColorChange(o......
  • 安装mysql服务添加到systemctl服务当中
    1、https://www.cnblogs.com/dahuo/p/16014689.html把mysqld添加至systemctl进行管理 #复制过去后,会sytemctl会自动识别的 cp/usr/local/mysql/support-f......
  • wpf 后台添加控件
    音乐播放列表,鼠标右键点击列表时,出现添加到歌单,做成每次右键点击时,后台新增选项了(也可以前台绑定数据源每次增删改后更新数据源)TextBlocktext=newTextBlock();text.......
  • 龙哥量化——文档目录3——通达信常用公式,主副图,条件选股,逻辑等详细分析
    常用公式这是目录分类中的第三篇,大家可以查看【总目录】https://www.cnblogs.com/long136/category/2247054.html标题地址1、基本指标 龙哥量化—通达信常......
  • wpf 后台修改控件颜色(颜色Brush类型新建)
    16进制、rgb格式、提供的颜色示例:xxx.Foreground=newSolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF"));xxx.Background=newSolidColorBrus......
  • William
    n.威廉(男子名,涵义:强而有力的战士)[男子名][英格兰人姓氏]威廉来源于古法语人名的诺曼底形式+日耳曼语,含义是“意愿+头盔,保护”(will,desire+helmet,protection)昵称......
  • Kuboard无法正常访问,提示Failed connected database
    问题:Kuboard无法正常访问现象:访问kuboard的10080端口时,直接提示无法连接数据库排查:kuboard采用的是dockerrun的方式进行部署dockerrun-d\--restart=u......
  • hgame2022 复现
    enterthepwnland​pthread_create()函数:创建线程intpthread_create(pthread_t*thread,constpthread_attr_t*attr,void......
  • socket通信编程C++实现
    socket提供了套接字,以方便我们想读取文件一样进行网络进程间的数据通信。在网络通信中,套接字一定是成对出现的。一端的发送缓冲区对应对端的接收缓冲区。我们使用同一个文......