21.1 动态TLS--《Windows核心编程》
应用程序通过调用一组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核心编程》的更多相关文章
- 《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技术 【转】
注:本文章转载于网络,源地址为:http://blog.csdn.net/ithzhang/article/details/7051558 本篇文章将介绍DLL显式链接的过程和模块基地址重定位及模块绑 ...
- 《Windows核心编程系列》二十谈谈DLL高级技术
本篇文章将介绍DLL显式链接的过程和模块基地址重定位及模块绑定的技术. 第一种将DLL映射到进程地址空间的方式是直接在源代码中引用DLL中所包含的函数或是变量,DLL在程序运行后由加载程序隐式的载入, ...
- CreateThread 线程操作与 _beginthreadex 线程安全(Windows核心编程)
0x01 线程的创建 线程不同于进程,Windows 中的进程是拥有 '惰性' 的,本身并不执行任何代码,而执行代码的任务转交给主线程,列如使用 CreateProcess 创建一个进程打开 Cmd ...
- windows核心编程 - 线程同步机制
线程同步机制 常用的线程同步机制有很多种,主要分为用户模式和内核对象两类:其中 用户模式包括:原子操作.关键代码段 内核对象包括:时间内核对象(Event).等待定时器内核对象(WaitableTim ...
- windows核心编程---第九章 同步设备IO与异步设备IO之同步IO
同步设备IO 所谓同步IO是指线程在发起IO请求后会被挂起,IO完成后继续执行. 异步IO是指:线程发起IO请求后并不会挂起而是继续执行.IO完毕后会得到设备的通知.而IO完成端口就是实现这种通知的很 ...
随机推荐
- arguments使用
arguments在函数中可以使用,表示包含了当前函数调用时传入的实参. arguments通过索引值获取实参,索引值从开始,按顺序依次表示函数调用时传过来的实参. 1 // arguments的使用 ...
- Liunx常用操作(四)-快速清空文件内容的方法(baseshell与vim)
一.baseshell下操作 1. $ : > filename #其中的 : 是一个占位符, 不产生任何输出. 2. $ > filename 3. $ echo "" ...
- Spring 事务失效场景总结
本文为博主原创,未经允许不得转载: 1. spring的事务注解@Transactional只能放在public修饰的方法上才起作用,如果放在其他非public(private,protected)方 ...
- 0xGame 2023【WEEK1】Crypto全解
What's CBC? 题目信息 from Crypto.Util.number import * from secret import flag,key def bytes_xor(a,b): a, ...
- 一键部署Docker中间件简单方法-redis为例
一键部署Docker中间件简单方法-redis为例 背景 想能够快速部署一些中间件. 写文档虽然可以, 但是总会有人问, 能够一键部署应该最好不过. 下载以及导出镜像 docker pull redi ...
- [转帖]使用 TiUP 部署 TiDB 集群
https://docs.pingcap.com/zh/tidb/stable/production-deployment-using-tiup TiUP 是 TiDB 4.0 版本引入的集群运维工具 ...
- [转帖]Pepper-Box - Kafka Load Generator
https://github.com/GSLabDev/pepper-box Pepper-Box is kafka load generator plugin for jmeter. It allo ...
- Java火焰图简单学习
前言 立的flags倒了太多次 自己还是太菜了.. 课题太大, 自己简单总结一下. 要是自己总结错了. 就不收费, 错就错了 !-_-! 第一步准备环境 一定要设置对java的HOME以及PATH路径 ...
- redis 设置密码之后,通过命令行一键刷新的办法
之前以为很麻烦 发现还是自己太low了. redis-cli -a Test1127 flushall
- (数据科学学习手札76)基于Python的拐点检测——以新冠肺炎疫情数据为例
本文对应代码.数据及文献资料已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes,对代码不感兴趣的朋友可以直接跳至2.2 探 ...