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的更多相关文章

  1. 【windows核心编程】线程局部存储TLS

    线程局部存储TLS, Thread Local Storage TLS是C/C++运行库的一部分,而非操作系统的一部分. 分为动态TSL 和 静态TLS 一.动态TLS 应用程序通过调用一组4个函数来 ...

  2. 线程局部存储TLS

    1 .使用线程局部存储的理由 当我们希望这个进程的全局变量变为线程私有时,而不是所有线程共享的,也就是每个线程拥有一份副本时,这时候就可以用到线程局部存储(TLS,Thread Local Stora ...

  3. 线程局部存储tls的使用

    线程局部存储(Thread Local Storage,TLS)主要用于在多线程中,存储和维护一些线程相关的数据,存储的数据会被关联到当前线程中去,并不需要锁来维护.. 因此也没有多线程间资源竞争问题 ...

  4. 线程局部存储TLS(thread local storage)

    同一全局变量或者静态变量每个线程访问的是同一变量,多个线程同时访存同一全局变量或者静态变量时会导致冲突,尤其是多个线程同时需要修改这一变量时,通过TLS机制,为每一个使用该全局变量的线程都提供一个变量 ...

  5. linux中的线程局部存储(TLS)

    http://blog.csdn.net/cywosp/article/details/26469435

  6. PE格式第八讲,TLS表(线程局部存储)

    PE格式第八讲,TLS表(线程局部存储) 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) 一丶复习线程相关知识 首先讲解 ...

  7. 线程局部存储(TLS)

    线程局部存储(TLS) 2011-10-11 09:59:28|  分类: Win32---API |  标签:tls   |举报 |字号 订阅   什么是线程局部存储 众所周知,线程是执行的单元,同 ...

  8. 【C# 线程】线程局部存储(TLS)理论部分 ThreadStatic|LocalDataStoreSlot|ThreadLocal<T>

    线程本地存储(TLS:Thread Local Storage) 线程本地存储(Thread Local Storage),字面意思就是专属某个线程的存储空间.变量大体上分为全局变量和局部变量,一个进 ...

  9. 基于TLS(线程局部存储)的高效timelog实现

    什么是timelog? 我们在分析程序性能的时候,会加入的一些logging信息记录每一部分的时间信息 timelog模块的功能就是提供统一的接口来允许添加和保存logging 我们正在用的timel ...

随机推荐

  1. Spring常用注解用法总结

    转自http://www.cnblogs.com/leskang/p/5445698.html 1.@Controller 在SpringMVC 中,控制器Controller 负责处理由Dispat ...

  2. IDEA 中.properties文件中文自动转Unicode编码及乱码问题

    问题描述: 在使用IDEA开发工具编辑属性文件(.properties)的时候出现中文自动转成了Unicode编码,或在读取属性文件的时候中文出现乱码. 问题解决: 进入 File -> Set ...

  3. Markdown常用的几种语法

    在VScode上面写的,现将代码粘贴如下:(在VScode里运行下即可) # Markdown语法 # Ctrl + k v 打开侧边预览 ## 一.加粗斜体删除线 **这是要加粗的文字** *这是要 ...

  4. 最大流——EK算法

    一.算法理论 [基本思想] 反复寻找源点s到汇点t之间的增广路径,若有,找出增广路径上每一段[容量-流量]的最小值delta,若无,则结束.在寻找增广路径时,可以用BFS来找,并且更新残留网络的值(涉 ...

  5. 【Python】Python内置函数dir详解

    1.命令介绍 最近学习并使用了一个python的内置函数dir,首先help一下: 复制代码代码如下: >>> help(dir)Help on built-in function ...

  6. java中使用POI+excel 实现数据的批量导入和导出

    java web中使用POI实现excel文件的导入和导出 文件导出 //导入excle表 public String exportXls() throws IOException{ //1.查询所有 ...

  7. Hadoop2.6.0伪分布式搭建

    环境: 1.Ubuntu14.04 首先要在linux系统上新建一个账户,比如就叫做hadoop,用于专门运行hadoop. 2.配置jdk 我是使用的版本是jdk1.8. 解压:创建/usr/jav ...

  8. SQL 视图 局部变量 全局变量 条件语句 事务 触发器

    一.视图 1.视图是一张虚拟表,他所存储的不是实际数据,而是查询语句,但我们可以对视图进行像数据表一样的操作. 2.为什么使用视图呢?我的理解是:1.在远程传输数据时,可以避免过长的查询字符,减少流量 ...

  9. 大数据Hadoop-1

    大数据Hadoop学习之搭建hadoop平台(2.2)   关于大数据,一看就懂,一懂就懵. 一.概述 本文介绍如何搭建hadoop分布式集群环境,前面文章已经介绍了如何搭建hadoop单机环境和伪分 ...

  10. hdu 3231 Box Relations (拓扑排序)

    Box Relations Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...