21.2 静态TLS--《Windows核心编程》
部分笔记来自于: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采用显式链接的方式,否则可能会出错!
21.2 静态TLS--《Windows核心编程》的更多相关文章
- 《Windows核心编程》读书笔记 上
[C++]<Windows核心编程>读书笔记 这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对 ...
- C++Windows核心编程读书笔记
转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...
- 【转】《windows核心编程》读书笔记
这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入 ...
- 【windows核心编程】 第六章 线程基础
Windows核心编程 第六章 线程基础 欢迎转载 转载请注明出处:http://www.cnblogs.com/cuish/p/3145214.html 1. 线程的组成 ① 一个是线程的内核 ...
- 【Windows】windows核心编程整理(下)
windows核心编程整理(上) windows核心编程整理(下) 线程的堆栈 每当创建一个线程时,系统就会为线程的堆栈(每个线程有他自己的堆栈)保留一个堆栈空间区域,并将一些物理存储器提交给这个以保 ...
- 《windows核心编程系列》十七谈谈dll
DLL全称dynamic linking library.即动态链接库.广泛应用与windows及其他系统中.因此对dll的深刻了解,对计算机软件开发专业人员来说非常重要. windows中所有API ...
- windows核心编程 - 线程同步机制
线程同步机制 常用的线程同步机制有很多种,主要分为用户模式和内核对象两类:其中 用户模式包括:原子操作.关键代码段 内核对象包括:时间内核对象(Event).等待定时器内核对象(WaitableTim ...
- windows核心编程---第九章 同步设备IO与异步设备IO之同步IO
同步设备IO 所谓同步IO是指线程在发起IO请求后会被挂起,IO完成后继续执行. 异步IO是指:线程发起IO请求后并不会挂起而是继续执行.IO完毕后会得到设备的通知.而IO完成端口就是实现这种通知的很 ...
- windows核心编程---第八章 使用内核对象进行线程同步
使用内核对象进行线程同步. 前面我们介绍了用户模式下线程同步的几种方式.在用户模式下进行线程同步的最大好处就是速度非常快.因此当需要使用线程同步时用户模式下的线程同步是首选. 但是用户模式下的线程同步 ...
- windows核心编程---第二章 字符和字符串处理
使用vc编程时项目-->属性-->常规栏下我们可以设置项目字符集合,它可以是ANSI(多字节)字符集,也可以是unicode字符集.一般情况下说Unicode都是指UTF-16.也 ...
随机推荐
- 6 Englishi 词根
9 pend/pends = hang 悬挂 depend de 向下 independent in 前缀 表否定: ent adj后缀 suspend sus=sub(便于发音) p ...
- 小白学正则表达式之 regexp
1. 正则表达式介绍 正则表达式是程序文本处理常用的模板模式,按照解析正则表达式的引擎可将正则表达式分为 POSIX 基础正则表达式(Basic regular expression,BRE) 引擎和 ...
- 理解 Kubernetes volume 和 共享存储
1. Kubernetes volume 文章 介绍了 Docker volume.与 docker volume 类似的,在 kubernetes 中存在 Pod 级别的 volume,Pod 的 ...
- 使用ensp搭建路由拓扑,并使用BGP协议实现网络互通实操
转载请注明出处: 1.使用ENSP搭建的网络拓扑如下: 数据准备: 设备名称 接口 IP地址 DeviceA Loopback 0 1.1.1.1/32 Eth 1/0/0 172.16.0.1/16 ...
- 【转】获取本地图片的URL
在写博客插入图片时,许多时候需要提供图片的url地址.作为菜鸡的我,自然是一脸懵逼.那么什么是所谓的url地址呢?又该如何获取图片的url地址呢? 首先来看一下度娘对url地址的解释:url是 ...
- [js] - 为子节点增加鼠标移入和移出的样式
var cards = document.querySelectorAll(".card"); for (let index = 0; index < cards.lengt ...
- java - for循环 排序数组 - 求数组最小值
主要是利用静态变量存储 public class Bubble2 { static int minNumber; public static void main(String[] args) { in ...
- 在TypeScript项目中搭配Axios封装后端接口调用
前言 本来是想发 next.js 开发笔记的,结果发现里面涉及了太多东西,还是拆分出来发吧~ 本文记录一下在 TypeScript 项目里封装 axios 的过程,之前在开发 StarBlog-Adm ...
- 配置Chrome支持网页内的frame跨域
前言 跨域限制可以保证安全,但是调试的时候关掉会更方便,然而现在网络上能找到的关闭跨域限制方法,在新版的Chrome浏览器上根本没用-- 经过一番摸索,发现用旧版的Chrome就可以绕过跨域限制,刚好 ...
- [转帖]Redis 内存淘汰策略 (史上最全)
1.前言 Redis内存淘汰策略,是被很多小伙伴忽略的知识盲区,注意,是盲区. 注意,Redis如果内存淘汰策略配置不合理,可能会导致Redis无法服务. 所以,使用此文,对Redis内存淘汰策略专门 ...