首页 > 其他分享 >【技术分享】线程本地存储(Thread Local Storage, TLS)

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

时间:2023-02-20 19:12:07浏览次数:54  
标签:TLS ErrorExit Thread VOID Storage lpvData TlsGetValue 线程 dwTlsIndex

开源项目:https://girakoo.com/

官方文档:https://learn.microsoft.com/en-us/windows/win32/procthread/using-thread-local-storage

简介

线程本地存储(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;
}

标签:TLS,ErrorExit,Thread,VOID,Storage,lpvData,TlsGetValue,线程,dwTlsIndex
From: https://www.cnblogs.com/girakoo/p/17138315.html

相关文章

  • 关于存入sessionStorage中boolean值拿出来为字符串
      上面是html部分,然后定义了变量   定义方法      在mounted中获取,然后刷新页面,打印类型为字符串      解决办法 ......
  • 微信小程序全局变量(globalData)和缓存(StorageSync)的区别和用法
    globalData和storage的区别一、app.globalData是全局变量,下次进入的时候,就要重新获取,一般用于:1、保存一些可能涉及安全类的数据,例如资源类,每次需要很准确的,就建议用全......
  • 通过代码,了解ThreadLocal
    在看此代码时,先看​​http://www.iteye.com/topic/103804​​ 如果ThreadLocal.set()进去的东西本来就是多个线程共享的同一个对象,那么多个线程的ThreadLocal.get()取得的......
  • ThreadLocal父子间通信的四种解决方案
    ThreadLocal父子间通信的四种解决方案ThreadLocal是存储在线程栈帧中的一块数据存储区域,其可以做到线程与线程之间的读写隔离。但是在我们的日常场景中,经常会出现父线程......
  • 使用ThreadLocal+OpenSessionInView优化Mybatis使用
    使用一个名为OpenSessionInView的servlet过滤器,简化在服务中使用mybatis的操作。   一、情况分析Mybatis的使用过程:1、获取配置文件2、获取session工厂......
  • threadlocal 原理详解
    ThreadLocal的基本概念在多线程并发中,我们需要保证共享变量(临界区)的安全性,因此在前面说起过synchronized和Lock锁,其中synchronized锁可以修饰方法或代码块,Lock锁可以修饰......
  • RabbitMQ 服务器启用 SSL/TLS
    为客户端和服务器生成自签名证书为了启用TLS/SSL,我们需要证书/密钥对。这可以借助OpenSSL为客户端和服务器生成自签名证书。生成自签名CA证书我们现在将使用OpenSSL创......
  • 为 RabbitMQ 服务器启用 SSL/TLS
    为RabbitMQ服务器启用SSL/TLS目录为RabbitMQ服务器启用SSL/TLS为客户端和服务器生成自签名证书在RabbitMQ服务器中启用TLS/SSL支持使用RabbitMQAssistant连......
  • 项目整体框架 + thread cache设计及实现
    你好,我是安然无虞。文章目录​​整体框架设计​​​​threadcache设计​​整体框架设计我们知道,现代的很多开发环境都是多核多线程的,所以在申请内存的时候,必然存在......
  • C++代码并行优化心得(OpenMP & TBB & Thread Pool)
    待更!  cmake引入OpenMP使用cmake中find_package指令查找openmp,格式如下:find_package(OpenMPREQUIRED)cmaketarget_link_libraries链接openmp:target_link_......