应用程序通过调用一组4个函数来使用动态 TLS,这些函数实际上最经常为 DLL 所使用。

通常情况下,如果DLL使用 TLS,那么当它用 DLL_PROCESS_ATTACH 标志调用它的 DllMain 函数时,它也调用TlsAlloc。当它用DLL_PROCESS_DETACH 调用 DllMain 函数时,它就调用 TlsFree。对 TlsSetValue 和 TlsGetValue 的调用很可能是在调用DLL中包含的函数时进行的。


动态TLS的使用

头文件:Windows.h
使用到的函数:TlsAlloc,TlsSetValue,TlsGetValue,TlsFree

(1)DWORD TlsAlloc();

作用:为调用该函数的线程分配一个线程局部存储序号,供其它三个函数使用
注意:一个进程最多分配TLS_MINIMUM_AVAILABLE个索引,目前定义为64,一个进程中所有线程分配的索引不会重复

int index=TlsAlloc()

(2)BOOL TlsSetValue(DWORD dwTlsIndex,LPVOID lpTlsValue);

作用:在指定的序号内存储数据,如TlsAlloc分配成功返回的序号

BOOL ret=TlsSetValue(index,(LPVOID)0x123456)

(3)LPVOID TlsGetValue(DWORD dwTlsIndex);

作用:取得指定序号内存储的数据

LPVOID lp=TlsGetValue(index);

(4)BOOL TlsFree(DWORD dwTlsIndex);

作用:释放指定序号

TlsFree(index);

#include<iostream>
#include<Windows.h>
using namespace std;
LPVOID fun(int ind) {
return TlsGetValue(ind);
} DWORD WINAPI testThr(LPVOID lpThreadParameter) {
int ind = (int)lpThreadParameter;
cout << "另启线程调用fun函数获取:" << fun(ind) << endl;
return 0;
} int main() {
DWORD index = TlsAlloc(); // 分配一个TLS索引
BOOL ret = TlsSetValue(index, (LPVOID)0x123456); // 设置该索引的值为0x123456
LPVOID p = TlsGetValue(index); // 根据该索引获取该值
cout << "主线程Main函数中:" << p << endl; // 输出该值
cout << "主线程调用fun函数:" << fun(index) << endl; // 调用fun函数获取该值
HANDLE hThr = CreateThread(NULL, 0, testThr, (LPVOID)index, NULL, NULL); // 创建一个新线程,传入索引
WaitForSingleObject(hThr, 5000); // 等待新建线程结束
TlsFree(index); // 释放该索引 // 进程和子线程很明显输出不一样
}

动态TLS原理

  

windows系统中每个进程都有一组正在使用标志(in-use-flag),如图21-1所示。每个标志可以被设为FREE或着INUSE,表示改TLS元素是否正在被使用。Microsoft保证至少有TLS_MINIMUM_AVAILABLE = 64个位标志可供使用。在必要的时候可以配更多,最多可达1000多个。而每一个线程拥有一个自己独立的TLS slot数组,用于存储TLS数据。

动态TLS的使用相对静态TLS稍微麻烦一点,但是无论是将其用在可执行文件中还是DLL中,都还是很简单的。而且当用在DLL中时,没有由于DLL链接方式而可能产生的问题,所以,如果要在DLL中用TLS,又不能保证客户始终采用隐式链接方式,那么请采用动态TLS的实现。

21.1 动态TLS--《Windows核心编程》的更多相关文章

  1. 《Windows核心编程》读书笔记 上

    [C++]<Windows核心编程>读书笔记 这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对 ...

  2. C++Windows核心编程读书笔记

    转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...

  3. 【转】《windows核心编程》读书笔记

    这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入 ...

  4. 【windows核心编程】 第六章 线程基础

    Windows核心编程 第六章 线程基础 欢迎转载 转载请注明出处:http://www.cnblogs.com/cuish/p/3145214.html 1. 线程的组成 ①    一个是线程的内核 ...

  5. 【Windows】windows核心编程整理(下)

    windows核心编程整理(上) windows核心编程整理(下) 线程的堆栈 每当创建一个线程时,系统就会为线程的堆栈(每个线程有他自己的堆栈)保留一个堆栈空间区域,并将一些物理存储器提交给这个以保 ...

  6. windows核心编程 DLL技术 【转】

    注:本文章转载于网络,源地址为:http://blog.csdn.net/ithzhang/article/details/7051558 本篇文章将介绍DLL显式链接的过程和模块基地址重定位及模块绑 ...

  7. 《Windows核心编程系列》二十谈谈DLL高级技术

    本篇文章将介绍DLL显式链接的过程和模块基地址重定位及模块绑定的技术. 第一种将DLL映射到进程地址空间的方式是直接在源代码中引用DLL中所包含的函数或是变量,DLL在程序运行后由加载程序隐式的载入, ...

  8. CreateThread 线程操作与 _beginthreadex 线程安全(Windows核心编程)

    0x01 线程的创建 线程不同于进程,Windows 中的进程是拥有 '惰性' 的,本身并不执行任何代码,而执行代码的任务转交给主线程,列如使用 CreateProcess 创建一个进程打开 Cmd ...

  9. windows核心编程 - 线程同步机制

    线程同步机制 常用的线程同步机制有很多种,主要分为用户模式和内核对象两类:其中 用户模式包括:原子操作.关键代码段 内核对象包括:时间内核对象(Event).等待定时器内核对象(WaitableTim ...

  10. windows核心编程---第九章 同步设备IO与异步设备IO之同步IO

    同步设备IO 所谓同步IO是指线程在发起IO请求后会被挂起,IO完成后继续执行. 异步IO是指:线程发起IO请求后并不会挂起而是继续执行.IO完毕后会得到设备的通知.而IO完成端口就是实现这种通知的很 ...

随机推荐

  1. xshell配置隧道转移规则

    钢铁知识库,一个学习python爬虫.数据分析的知识库.人生苦短,快用python. xshell是什么 通俗点说就是一款强大ssh远程软件,可以方便运维人员对服务器进行管理操作,功能很多朋友们自行探 ...

  2. AHB-SRAMC Design-03

    SRAMC SRAM CORE 8块memory进行广播信号,例化8片memory

  3. 【js】 Object.prototype.toString.call()

    1,Object.prototype.toString这个方法的作用是什么  判断数据类型 2,为什么要用这个方法 是因为  js 中 一般的类型判断 对于 null,数组,对象 , 都会返回一样的结 ...

  4. 02-MySQL基本操作

    SQL 的一些简单语法规则 结束符 SQL 指令需要语句结束符,默认是英文分号;. 当然,还有另外两个结束符: \g 与英文分号;等效. \G:将查到的结构旋转90度变成纵向. 反引号`` SQL语句 ...

  5. [转帖] jq命令用法总结

    https://www.cnblogs.com/codelogs/p/16324928.html 原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 如果说要给Li ...

  6. shell补遗_一个巨简单的保证服务存活的脚本

    Shell补遗 背景 公司一台机器总是会在没有更新补丁的情况下启动失败. 查看所有的配置都没有问题. 但是就是不启动 没办法,准备写一个检查进行启动. 最近写shell很少. 所以总结一下. 思路 判 ...

  7. [转帖]01-rsync备份方式

    https://developer.aliyun.com/article/885783?spm=a2c6h.24874632.expert-profile.284.7c46cfe9h5DxWK 简介: ...

  8. [转帖]【JVM】堆内存与栈内存详解

    堆和栈的定义 java把内存分成栈内存和堆内存. (1)栈内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配. 当在一段代码块中定义一个变量时,java就在栈中为这个变量分 ...

  9. 验证功能访问Redis的次数和命令

    背景 公司内部在进行性能调优, 调优有多个方法. 应用Redis方面主要的调优有: 1. 进行redis键值对大小的处理. 2. 进行redis键值对过期时间的处理. 3. 减少连接数,减少网络带宽. ...

  10. [专题]测试发现部分NVMe SSD的掉电数据保护功能让人失望

    https://www.cnbeta.com/articles/tech/1240441.htm 这个有点过分了. 苹果开发者 Russ Bishop 在一份测试报告中指出:即使掉电保护已经是个绕不开 ...