线程局部存储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. 10 harsh truths that will help you grow

    10 harsh truths that will help you grow帮你成长的10个残酷事实In the game of life, if it often seems like you’r ...

  2. python url编码,解码

    >>> urllib.unquote('%E4%B8%BD%E6%B1%9F') >>> data '\xe4\xb8\xbd\xe6\xb1\x9f' >& ...

  3. 手动安装UniDAC的过程

    每次安装都不一样,而且有时候挺麻烦的,所以记下来.我这次安装过程是这样的: 0. 修改Source\Delphi7\Make.bat,填入正确的IdeDir 1.找到source\delphi7目录, ...

  4. 安装nginx创建错误

    ./configure: error: the HTTP gzip module requires the zlib library. 解决: yum install -y zlib-devel -- ...

  5. Java API —— TreeMap类

    1.TreeMap类概述         键是红黑树结构,可以保证键的排序和唯一性 2.TreeMap案例         TreeMap<String,String>         T ...

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

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

  7. 在Tomcat中配置数据源

    使用工具:TOMCAT 7.0.52.IntelliJ IDEA 13.0.2.JSF 2.0+.SqlServer.jtds-1.2.5.jar 搞了好久都没成功,开始使用注解引入DataSourc ...

  8. BAT面经

    http://bbs.csdn.net/topics/390734210?page=4 注意评论以及文章原地址

  9. WebBrowser.ObjectForScripting 属性的使用

    主要是winform窗体中使用了webBrowser控件,webBrowser中调用javascript操作窗体里面的后台方法,使用下面的两句. this.webBrowser1.ObjectForS ...

  10. jquery select操作和联动操作

    (function(){ //select操作 $.fn.loadSelect = function(opt){ opt = $.extend({}, { required:false,//为真则添加 ...