线程局部存储TLS, Thread Local Storage

TLS是C/C++运行库的一部分,而非操作系统的一部分。

分为动态TSL 和 静态TLS

一、动态TLS

应用程序通过调用一组4个函数来使用动态TLS, 这些函数实际上最为DLL所使用。

系统中的每个进程都有一组 正在使用标志(in-use flag), 每个标志可被设置为FREE 或者 INUSE, 表示该TLS元素是否正在使用。

微软平台保证至少有TLS_MINUMUM_AVALIABLE个标志位可供使用, TLS_MINUMUM_AVALIABLE在WinNT.h中被定义为64. 系统会在需要的时候分配更多的TLS元素,最多可达1000多个。

下面介绍下函数

DWORD    TlsAlloc();

这个函数让系统对进程中中的标志位进行检索并找到一个FREE标志,然后将该元素的标志从FREE置为INUSE, 并让TlsAlloc返回该元素的索引(下标)。

一个DLL(或应用程序)通常会将此索引保存在一个全局变量中,在整个进程范围内访问。

如果找不到一个标志为FREE的元素,则函数返回TLS_OUT_OF_INDEXES(在WinBase.h中被定义为0XFFFFFFFF)。

每个线程都有一个PVOID数组,每个线程使用每次TlsAlloc成功时的返回值作为各自线程中该数组的索引。

注意:该函数返回时会将每个线程中的数组对应的索引位置元素清零!

返回值:

失败:TLS_OUT_OF_INDEXES

成功:其他

BOOL    TlsSetValue(

DWORD   dwTlsIndex,   // TlsAlloc()函数的返回值

PVOID      pvTlsValue    //要设置的值

);

返回值:

TRUE: 成功

FALSE:失败

该函数的主调线程只能更改自己的数组,而不能修改其他线程的数组。

PVOID   TlsGetValue(

DWORD  dwTlsIndex    //TlsAlloc()函数的返回值

);

BOOL     TlsFree(

DWORD   dwTlsIndex    //TlsAlloc()函数的返回值

);

将该标志置为FREE, 并且将元素值清零。

二、静态TLS

__declspec(thread)   int  g_value = 0;

__declspec(thread)前缀是微软为VC++编译器增加的一个修饰符,它告诉编译器应该在可执行文件或DLL中,把对应的变量放到他自己的段中。

__declspec(thread)后面的变量必须声明为 全局变量 或 静态变量(全局或局部都可), 不可以将局部变量声明为__desclspec(thread)类型。

当编译器对程序进行编译的时候,会将所有TLS变量放到他自己的段中,这个段为.tls段。 链接器会将所有对象模块中的.tls段合并成一个大的.tls段,并将他保存到生成的exe或DLL文件中。

当系统将应用程序载入到内存的时候,会查看可执行文件中的.tls段,并分配一块足够的的内存来保存所有的静态TLS变量。 每当应用程序中的代码引用到这些变量之一事,相应的引用会被解析到刚分配的这块内存中的一个位置。 因此编译器必须生成额外的代码来引用静态TLS。

如果进程创建了一个新的线程,那么系统会得知这一情况并自动分配另一块内存来保存新线程的静态TLS变量。

当隐式加载DLL的时候:

如果exe使用了静态TLS, DLL也使用了TSL, 系统会首先确定exe的.tls段的大小,并将exe所有链接到的DLL的.tls段的大小相加。当系统在创建新线程的时候,会自动分配一块足够大的内存来保证应用程序和所有隐式链接的DLL需要的TLS变量。

当显式加载DLL的时候:

某DLL包含了静态TLS变量, exe使用LoadLibrary来显式加载DLL。 系统查看进程中已有线程,然后根据DLL中的TLS段扩大每个线程的TLS内存块。

当调用FreeLibrary释放DLL时,则该进程中的所有线程的TLS内存块也应该相应的缩减,缩减的部分是DLL中的TLS的部分。

【windows核心编程】线程局部存储TLS的更多相关文章

  1. windows核心编程 - 线程同步机制

    线程同步机制 常用的线程同步机制有很多种,主要分为用户模式和内核对象两类:其中 用户模式包括:原子操作.关键代码段 内核对象包括:时间内核对象(Event).等待定时器内核对象(WaitableTim ...

  2. windows核心编程 - 线程基础

    一.基本概念: 一个进程至少需要一个线程. 组成:一个线程包括仅包括一个线程堆栈和一个线程内核对象 线程堆栈:用于维护线程在执行代码时需要的所有函数参数和局部变量 线程内核对象:操作系统用它来对线程实 ...

  3. Windows核心编程&线程

    1. 线程上下文:线程内核对象保存线程上一次执行时的CPU寄存器状态 2. 线程上下文切换 3. windows操作系统为抢占式多线程操作系统,系统可以在任何时刻停止一个线程而另行调度另外一个线程.我 ...

  4. windows核心编程---第八章 使用内核对象进行线程同步

    使用内核对象进行线程同步. 前面我们介绍了用户模式下线程同步的几种方式.在用户模式下进行线程同步的最大好处就是速度非常快.因此当需要使用线程同步时用户模式下的线程同步是首选. 但是用户模式下的线程同步 ...

  5. 【windows核心编程】 第八章 用户模式下的线程同步

    Windows核心编程 第八章 用户模式下的线程同步 1. 线程之间通信发生在以下两种情况: ①    需要让多个线程同时访问一个共享资源,同时不能破坏资源的完整性 ②    一个线程需要通知其他线程 ...

  6. 【windows核心编程】 第六章 线程基础

    Windows核心编程 第六章 线程基础 欢迎转载 转载请注明出处:http://www.cnblogs.com/cuish/p/3145214.html 1. 线程的组成 ①    一个是线程的内核 ...

  7. Windows核心编程学习九:利用内核对象进行线程同步

    注:源码为学习<Windows核心编程>的一些尝试,非原创.若能有助于一二访客,幸甚. 1.程序框架 #include "Queue.h" #include <t ...

  8. 《windows核心编程系列》十九谈谈使用远程线程来注入DLL。

    windows内的各个进程有各自的地址空间.它们相互独立互不干扰保证了系统的安全性.但是windows也为调试器或是其他工具设计了一些函数,这些函数可以让一个进程对另一个进程进行操作.虽然他们是为调试 ...

  9. 用户模式下的线程同步的分析(Windows核心编程)

    线程同步 同一进程或者同一线程可以生成许多不同的子线程来完成规定的任务,但是多个线程同时运行的情况下可能需要对某个资源进行读写访问,比如以下这个情况:创建两个线程对同一资源进行访问,最后打印出这个资源 ...

随机推荐

  1. 李洪强iOS开发之让您的Xcode键字如飞

    手指在键盘上飞速跳跃,终端上的代码也随着飞舞,是的这确实很酷.优秀的程序员总是这么一群人,他们不拘于现状,不固步自封,他们喜欢新奇的事,他们把自己发挥到极致. 指法攻略 放下您钟爱的鼠标吧,在前行之中 ...

  2. JTable单元格放自定义控件(一)-如何在JTable的单元格放JPanel

    原文链接:http://blog.sina.com.cn/s/blog_7f1c8c710101hdpf.html 最近自己尝试着模仿着实现一款非常有名的进销库存管理系统(智慧记)里面的一个功能.功能 ...

  3. Xamarin.Android 入门之:Android的生命周期

    一.前言 活动是Android应用程序的基本构建块,他们可以在许多不同的状态存在.当你把一个Android程序置于后台,过一段时间再打开发现之前的数据还存在. 二.活动状态 下面的图表说明了一个活动可 ...

  4. Intellij idea使用postgresql 反向生成实例, 'Basic' attribute type should not be 'Object'

    mapped type不能Object? 本人使用 intellij idea 15 , postgresql 9.4,在开发java ee . 在用 Hibernate时, 需要用数据库表反向生成实 ...

  5. 34. Search for a Range

    题目: Given a sorted array of integers, find the starting and ending position of a given target value. ...

  6. SQL Server数据库多种方式查找重复记录

    摘要:SQL Server是一个关系数据库管理系统,SQL Server数据库的应用是很多的,SQL Server数据库赢得了广大用户的青睐,本文将主要为大家介绍关于SQL Server数据库中查找重 ...

  7. SQL Server查询优化方法(查询速度慢的原因很多,常见如下几种) .

    今天看到一位博友的文章,觉得不错,转载一下,希望对大家有帮助,更多文章,请访问:http://blog.haoitsoft.com 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺 ...

  8. 机器学习 —— 概率图模型(Homework: Factors)

    Talk is cheap, I show you the code 第一章的作业主要是关于PGM的因子操作.实际上,因子是整个概率图的核心.对于有向图而言,因子对应的是CPD(条件分布):对无向图而 ...

  9. MapReduce编程系列 — 5:单表关联

    1.项目名称: 2.项目数据: chile    parentTom    LucyTom    JackJone    LucyJone    JackLucy    MaryLucy    Ben ...

  10. IOS把文件保存进沙盒目录

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); NSS ...