线程局部存储 TLS
C/C++运行库提供了TLS(线程局部存储),在多线程还未产生时,可以将数据与正在执行的线程关联。strtok()函数就是一个很好的例子。与它一起的还有strtok_s(),_tcstok_s()等等函数,其实_tcs 是 wcs 的另外一种写法,表示宽字符存储,_s 是微软定义的安全函数,通常比普通函数多一个参数。以_tcstok_s()为例,
int main(int argc, char* argv[])
{
wchar_t Source[] = L"192.168.255.255";
wchar_t doc[] = L".";
wchar_t* next_token;
wchar_t* Dest = _tcstok_s(Source, doc, &next_token); //strtok_s
int i = 1;
while (Dest != NULL)
{
printf("Dest[%d]: %S\r\n", i, Dest);
Dest = _tcstok_s(NULL, doc, &next_token);
i++;
}
return 0;
}
如果提示函数不认识,添加头文件 #include <tchar.h>
代码很简单,将源字符串以 “.”为分隔符分开,并输出。注意第二次调用_tcstok_s函数时,第一参数传NULL,这是因为第一次调用时已经将字符串保存在自己的静态变量中,后面再使用就可以引用保存的地址。
但在多线程编程下,第一个线程调用_tcstok_s,当它再次调用之前,另一个线程也可能调用它。这样就导致第一次的内容被覆盖。这就用到TLS的内容了。
1.静态TLS
#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;
__declspec(thread) int value = 0;
DWORD WINAPI ThreadProc(LPVOID Param);
int main(int argc, char* argv[])
{
value = 1;
HANDLE ThreadHandle = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
WaitForSingleObject(ThreadHandle, INFINITE);
cout << "main " << value << endl;
return 0;
}
DWORD WINAPI ThreadProc(LPVOID Param)
{
value = 10;
cout << value << endl;
return 0;
}
__declspec(thread) 这个修饰符告诉编译器,将这个值放在.tls段中,如果不写,会放在.data段里。
结果:
定义了__declspec(thread) 输出 10 main 1
没定义__declspec(thread) 输出 10 main 10
2.动态TLS
#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;
int __Index[3] = { 0 };
char Name[3][20] = { {"qwe"},{"asd"},{"zxc"} };
DWORD WINAPI ThreadProc(LPVOID Param);
int main(int argc, char* argv[])
{
int i = 0;
DWORD ThreadID[3] = { 0 };
HANDLE ThreadHandle[3] = { 0 };
for (; i < 3; i++)
{
__Index[i] = TlsAlloc(); // 对位标志进行检索,找到一个FREE标志,其实就是预定了一个索引
if (__Index[i] <= TLS_MINIMUM_AVAILABLE)
{
ThreadHandle[i] = CreateThread(NULL, 0, ThreadProc, (LPVOID)(Name[i]), 0, &ThreadID[i]);
}
}
WaitForMultipleObjects(3, ThreadHandle, TRUE, INFINITE);
return 0;
}
DWORD WINAPI ThreadProc(LPVOID Param)
{
char* key = new char[20];
memcpy(key, (char*)Param, 20);
TlsSetValue(__Index[0], key); //将值与索引关联,注意,微软实现它时,牺牲了错误检查,即使错误的索引,也会分配
for (int i = 0; i < 10; i++)
{
Sleep(1);
printf("%s\r\n", (char*)TlsGetValue(__Index[0])); // 返回 索引中的值
}
free(key);
return 0;
}
一般来说,这两种TLS在创建DLL时更加有用。
线程局部存储 TLS的更多相关文章
- 【windows核心编程】线程局部存储TLS
线程局部存储TLS, Thread Local Storage TLS是C/C++运行库的一部分,而非操作系统的一部分. 分为动态TSL 和 静态TLS 一.动态TLS 应用程序通过调用一组4个函数来 ...
- 线程局部存储TLS
1 .使用线程局部存储的理由 当我们希望这个进程的全局变量变为线程私有时,而不是所有线程共享的,也就是每个线程拥有一份副本时,这时候就可以用到线程局部存储(TLS,Thread Local Stora ...
- 线程局部存储tls的使用
线程局部存储(Thread Local Storage,TLS)主要用于在多线程中,存储和维护一些线程相关的数据,存储的数据会被关联到当前线程中去,并不需要锁来维护.. 因此也没有多线程间资源竞争问题 ...
- 线程局部存储TLS(thread local storage)
同一全局变量或者静态变量每个线程访问的是同一变量,多个线程同时访存同一全局变量或者静态变量时会导致冲突,尤其是多个线程同时需要修改这一变量时,通过TLS机制,为每一个使用该全局变量的线程都提供一个变量 ...
- linux中的线程局部存储(TLS)
http://blog.csdn.net/cywosp/article/details/26469435
- PE格式第八讲,TLS表(线程局部存储)
PE格式第八讲,TLS表(线程局部存储) 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) 一丶复习线程相关知识 首先讲解 ...
- 线程局部存储(TLS)
线程局部存储(TLS) 2011-10-11 09:59:28| 分类: Win32---API | 标签:tls |举报 |字号 订阅 什么是线程局部存储 众所周知,线程是执行的单元,同 ...
- 【C# 线程】线程局部存储(TLS)理论部分 ThreadStatic|LocalDataStoreSlot|ThreadLocal<T>
线程本地存储(TLS:Thread Local Storage) 线程本地存储(Thread Local Storage),字面意思就是专属某个线程的存储空间.变量大体上分为全局变量和局部变量,一个进 ...
- 基于TLS(线程局部存储)的高效timelog实现
什么是timelog? 我们在分析程序性能的时候,会加入的一些logging信息记录每一部分的时间信息 timelog模块的功能就是提供统一的接口来允许添加和保存logging 我们正在用的timel ...
随机推荐
- Android中StackOverflow的问题
最近出现了一个让人抓狂的问题. 现在的项目中,制作了一个界面非常复杂.Fragment中嵌套下拉刷新的Listview 这样一个布局,在3.0以上的手机上都表现良好问题!但是在2.x的比较弱爆的手机上 ...
- 「题目代码」P1034~P1038(Java)
P1034 C基础-求同存异 import java.util.*; import java.io.*; import java.math.BigInteger; public class Main ...
- github 初始化操作小记
Git作为一种越来越重要的工具,github又如此流行,现在就简单记录一下git的基础操作,希望能帮助大家快速体验入门! 1 查看本地是否存在”公钥”和”私钥” 如果没有,则执行: ssh-keyg ...
- OpenCV实现SIFT图像拼接源代码
OpenCV实现SIFT和KDtree和RANSAC图像拼接源代码,此源代码由Opencv2.4.13.6和VC++实现,代码本人已经调试过,完美运行,效果如附图.Opencv2.4.13.6下载地址 ...
- 软件工程项目组Z.XML会议记录 2013/11/20
软件工程项目组Z.XML会议记录 [例会时间]2013年11月20日星期三21:00-22:00 [例会形式]小组讨论 [例会地点]学生公寓3号楼会客厅 [例会主持]李孟 [会议记录]李孟 会议整体流 ...
- HDU 1398 Square Coins 整数拆分变形 母函数
欢迎参加——BestCoder周年纪念赛(高质量题目+多重奖励) Square Coins Time Limit: 2000/1000 MS (Java/Others) Memory Limit ...
- jetty-maven-plugin
<plugins> <plugin> <groupId>org.eclipse.jetty</groupId> <artifact ...
- Win10 1803安装Ubuntu1804子系统
1.win10应用商店选择Ubuntu1804安装 点击打开会提示https://docs.microsoft.com/zh-cn/windows/wsl/install-win10 2.用管理员po ...
- 【log4net】- 日志使用教程
一.log4net简介: 1. Log4net的优点: 几乎所有的大型应用都会有自己的用于跟踪调试的API.因为一旦程序被部署以后,就不太可能再利用专门的调试工具了.然而一个管理员可能需要有一套强大的 ...
- WCF身份验证一:消息安全模式之<Certificate>身份验证
消息安全模式的证书身份验证方式,基于WSHttpBinding绑定协议的实现过程.主要内容:基本概念,然后是制作证书.服务端配置.客户端配置.总结.这里应该和Transport传输安全模式之证书身份验 ...