第二十一章、线程局部存储(TLS)

第二十一章、线程局部存储(TLS),第1张

第二十一章、线程局部存储(TLS) 文章目录

第一章、VS2019环境编程下的错误处理

第二章、ANSI与Unicode之间的字符处理


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录
  • 文章目录
  • 一、基本概念
  • 二、基本使用
  • 三、例子
    • 分析:
  • 总结


一、基本概念

线程局部存储(TLS),是一种变量的存储方法,这个变量在它所在的线程内是全局可访问的,但是不能被其他线程访问到,这样就保持了数据的线程独立性。而熟知的全局变量,是所有线程都可以访问的,这样就不可避免需要锁来控制,增加了控制成本和代码复杂度。

二、基本使用

环境:VS 2022 preview
头文件:Windows.h
使用到的函数:TlsAlloc,TlsSetValue,TlsGetValue,TlsFree

TlsAlloc函数:

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

TlsSetValue函数:

函数原型:BOOL TlsSetValue(DWORD dwTlsIndex,LPVOID lpTlsValue);
作用:在指定的序号内存储数据,如TlsAlloc分配成功返回的序号
使用:
BOOL ret=TlsSetValue(index,(LPVOID)0x123456)

TlsGetValue函数:

函数原型:LPVOID TlsGetValue(DWORD dwTlsIndex);
作用:取得指定序号内存储的数据
使用:
LPVOID lp=TlsGetValue(index);

TlsFree函数:

函数原型:BOOL TlsFree(DWORD dwTlsIndex);
作用:释放指定序号
使用:
TlsFree(index);
三、例子
#include
#include
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);		//释放该索引
}

运行结果:

分析:

以上代码,首先创建一个fun函数,作用为根据传入的索引调用TlsGetValue函数获取并返回该索引的值。
后在main函数中调用TlsAlloc分配一个TLS索引,再调用TlsSetValue设置该索引值为0x123456,接着进行对比实验。
分别在主线程main函数中直接调用TlsGetValue获取,调用fun函数获取,以及创建另一个线程调用fun函数获取,并分别输出,可以看到,只有主线程能够获取到该值,另启动线程获取的值为0

总结

线程局部存储(TLS),可以存储只能该线程使用的数据。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5636004.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存