【技术分享】线程本地存储(Thread Local Storage, TLS)

在项目开发中,遇到了关于TLS相关的问题。为了了解该机制的用途,在微软的官网查找了一些资料。

本文参考官方文档, 简单介绍一下TLS的用途与使用方法。

微软官方文档链接

一、简介

线程本地存储(TLS),可以使多个线程,通过TlsGetValue函数,获得各自线程独立的数据。

即,在进程中通过TlsAlloc,可以申请一个索引值(index)。

在不同的线程中,通过TlsSetValue/TlsGetValue,可以获得不同的数据。

注:TlsSetValue/TlsGetValue内部可能是通过线程ID进行了绑定,实现的功能。

二、官方示例(有调整)及个人注解

#include <windows.h>
#include <stdio.h> #define THREADCOUNT 4
DWORD dwTlsIndex; VOID ErrorExit(LPCSTR message);
VOID CommonFunc(VOID);
DWORD WINAPI ThreadFunc(VOID); // main入口函数
int main(VOID)
{
DWORD IDThread;
HANDLE hThread[THREADCOUNT];
int i; // 通过TlsAlloc函数,创建进程的tls索引,保存在dwTlsIndex
if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
{
// 如果返回TLS_OUT_OF_INDEXES,说明创建失败
ErrorExit("TlsAlloc failed");
} // 通过for循环创建多个线程
for (i = 0; i < THREADCOUNT; i++)
{
hThread[i] = CreateThread(NULL, // 默认security属性
0, // 默认stack size
(LPTHREAD_START_ROUTINE)ThreadFunc, // 线程处理函数
NULL, // no thread function argument
0, // use default creation flags
&IDThread); // returns thread identifier // 判定创建线程结果
if (hThread[i] == NULL)
ErrorExit("CreateThread error\n");
} // 等待所有线程执行完毕,退出循环
for (i = 0; i < THREADCOUNT; i++)
WaitForSingleObject(hThread[i], INFINITE); TlsFree(dwTlsIndex); return 0;
} VOID ErrorExit(LPCSTR message)
{
// 输出线程错误消息,并退出进程
fprintf(stderr, "%s\n", message);
ExitProcess(0);
} VOID CommonFunc(VOID)
{
LPVOID lpvData; // 取得dwTlsIndex指向的空间(此时获得的数据是各自线程通过TlsSetValue设置进去的)
lpvData = TlsGetValue(dwTlsIndex);
if ((lpvData == 0) && (GetLastError() != ERROR_SUCCESS))
ErrorExit("TlsGetValue error"); // 可以使用该空间数据
printf("common: thread %d: lpvData=%lx\n",
GetCurrentThreadId(), lpvData); Sleep(5000);
} DWORD WINAPI ThreadFunc(VOID)
{
LPVOID lpvData; // 申请动态空间,每个线程创建独自的空间。
lpvData = (LPVOID)LocalAlloc(LPTR, 256); // 将动态空间绑定到Tls对应的Index空间上
if (!TlsSetValue(dwTlsIndex, lpvData))
ErrorExit("TlsSetValue error"); printf("thread %d: lpvData=%lx\n", GetCurrentThreadId(), lpvData); // 通用处理函数,可以在内部使用TlsGetValue获得的数值
CommonFunc(); // 释放动态空间,每个线程创建独自的空间。
lpvData = TlsGetValue(dwTlsIndex); if (lpvData != 0)
LocalFree((HLOCAL)lpvData); return 0;
}

【GiraKoo】线程本地存储(Thread Local Storage, TLS)的更多相关文章

  1. 线程本地存储(Thread Local Storage, TLS)简单分析与使用

    在多线程编程中, 同一个变量, 如果要让多个线程共享访问, 那么这个变量可以使用关键字volatile进行声明; 那么如果一个变量不想使多个线程共享访问, 那么该怎么办呢? 呵呵, 这个办法就是TLS ...

  2. ionic 通过PouchDB + SQLite来实现app的本地存储(Local Storage)

    首先声明,本教程参考国外网站(http://gonehybrid.com/how-to-use-pouchdb-sqlite-for-local-storage-in-your-ionic-app/) ...

  3. [转]ionic 通过PouchDB + SQLite来实现app的本地存储(Local Storage)

    本文转自:http://www.cnblogs.com/ailen226/p/ionic.html 首先声明,本教程参考国外网站(http://gonehybrid.com/how-to-use-po ...

  4. Atitit usrqbg1821 Tls 线程本地存储(ThreadLocal Storage 规范标准化草案解决方案ThreadStatic

    Atitit usrqbg1821 Tls 线程本地存储(ThreadLocal Storage 规范标准化草案解决方案ThreadStatic 1.1. ThreadLocal 设计模式1 1.2. ...

  5. 线程本地存储TLS(Thread Local Storage)的原理和实现——分类和原理

    原文链接地址:http://www.cppblog.com/Tim/archive/2012/07/04/181018.html 本文为线程本地存储TLS系列之分类和原理. 一.TLS简述和分类 我们 ...

  6. 线程本地存储TLS(Thread Local Storage)的原理和实现——分类和原理

    本文为线程本地存储TLS系列之分类和原理. 一.TLS简述和分类 我们知道在一个进程中,所有线程是共享同一个地址空间的.所以,如果一个变量是全局的或者是静态的,那么所有线程访问的是同一份,如果某一个线 ...

  7. 线程本地存储(动态TLS和静态TLS)

    线程本地存储(TLS) 对于多线程应用程序,如果线程过于依赖全局变量和静态局部变量就会产生线程安全问题.也就是一个线程的使用全局变量可能会影响到其他也使用此全局变量的线程,有可能会造成一定的错误,这可 ...

  8. 利用HTML5开发Android(7)---HTML5本地存储之Database Storage

    在上一篇<HTML5本地存储之Web Storage篇>中,简单介绍了如何利用localStorage实现本地存储:实际上,除了sessionStorage和localStorage外,H ...

  9. .NET:线程本地存储、调用上下文、逻辑调用上下文

    .NET:线程本地存储.调用上下文.逻辑调用上下文 目录 背景线程本地存储调用上下文逻辑调用上下文备注 背景返回目录 在多线程环境,如果需要将实例的生命周期控制在某个操作的执行期间,该如何设计?经典的 ...

  10. C# 线程本地存储 调用上下文 逻辑调用上下文

    线程本地存储 using System; using System.Threading; using System.Threading.Tasks; namespace ConsoleAppTest ...

随机推荐

  1. 关于 Android sdk manager 的安装问题

    最近刚刚接触小程序测试,故此需要搭建环境 我用的是python3.6+appium1.8.2+Android sdk manager 关于应用程序,大家有需要的话,可以找我要. 1.关于安装Andro ...

  2. SSRF Server-Side Request Forgery(服务器端请求伪造)

    什么是SSRF? 犹如其名,SSRF(Server-Side Request Forgery)服务端请求伪造,攻击者可以控制服务器返回的页面,借用服务器的权限访问无权限的页面. 这是一个允许恶意用户导 ...

  3. 【2019CCPC秦皇岛:A】Angle Beats 分类讨论 (unordered_map 加 hash)

    题意:n个给定点,q个询问点,每次询问给出一个坐标A,问从n中选定两个点B,C,有多少种方案使得ABC是个直角三角形. 思路:直角三角形能想的就那几个,枚举边,枚举顶点,这个题都行,写的枚举顶点的,A ...

  4. 熹乐科技范维肖CC:基于开源 YoMo 框架构建“全球同服”的 Realtime Metaverse Application

    前言 在「RTE2022 实时互联网大会」中,熹乐科技创始人 & CEO @范维肖CC 以<基于开源 YoMo 框架构建"全球同服"的 Realtime Metave ...

  5. ArcMap将Python写的代码转为工具箱与自定义工具

      本文介绍在ArcMap软件中,通过已有的Python脚本程序,建立新的工具箱并在其中设置自定义工具的方法.   通过本文介绍的操作,我们便可以实现将自己的Python代码封装,并像其他ArcGIS ...

  6. Trie树结构

    PrefixTree 208. 实现 Trie (前缀树) Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键.这一数据结构 ...

  7. 8.XSS和CSRF漏洞

    XSS和CSRF漏洞 目录 XSS和CSRF漏洞 XSS漏洞介绍 XSS分类 利用XSS漏洞如何实行攻击 利用XSS盗取用户的Cookie 利用XSS实行钓鱼 利用XSS进行键盘监控 CSRF漏洞介绍 ...

  8. Java泛型: 主要知识点总结

    Java泛型:主要知识点总结 1 泛型的好处 解决元素存储的安全性问题. 解决获取数据元素时,需要类型强制转换的问题. Java泛型可以保证如果程序在编译时没有发出警告,运行.时就不会产生ClassC ...

  9. vue中实现video的动态src绑定

    Vue中实现video的动态src 试了网上的$refs方法发现并没有用 解决方案: 通过require方法  <div>     <video :src='url' @click= ...

  10. [Java]算法练习:新农村建设

    1 题目描述 from 网友 CASE1 输入 A1 A8 输出 [A1,A2,A3,A4,A5,A6,A7,A8] CASE2 输入 A1 K1 输出 [A1,B1,C1,D1,E1,F1,G1,H ...