线程本地存储器

——Windows核心编程学习手札之二十一

C/C++运行期库使用线程本地存储器,运行期库是在多线程应用程序出现前设计的,因此运行期库里的大多数函数是用于单线程应用程序的。函数strtok就是如此,函数初次调用strtok时,该函数传递一个字符串地址,并将字符串地址保存在自己的静态变量中,当再次调用该函数并传递NULL时,函数就引用保存的字符串地址。在多线程环境下,一个线程可以调用strtok,然后在其再次调用strtok之前,另一个线程也调用了strtok,这种情况下,第二个线程会在第一个线程不知情情况下,让strtok用一个新地址改写strtok的静态变量,而第一个线程再次调用strtok时将使用第二个线程的字符串,这样会导致难以发现和排除的错误。

为解决上面问题, C/C++运行期库使用了TLS,每个线程均被赋予自己的字符串指针,供strtok函数使用,类似的C/C++运行期库函数还有asctime和gmtime。如应用程序严重依赖全局变量和静态变量,那TLS能够解决问题,但编程应尽量减少对这些变量的使用,而更多地依赖自动(基于堆栈的)变量和通过函数的参数传递的数据,因为基于堆栈的变量总是和特定的线程联系的。

动态TLS:

先调用DWORD TlsAlloc()告诉系统对进程中的位标志进行扫描,找出FREE标志,然后系统将标志由FREE改为INUSE,并且TlsAlloc返回位数组中的标志的索引。

将一个值放入线程的数组中,调用

BOOL TlsSetValue(

DWORD dwTlsIndex,

PVOID pvTlsValue);

函数将PVOID值放入线程的数组中,由dwTlsIndex参数标识的索引处。

若要从线线程的数组中检索一个值,调用

PVOID TlsGetVluae(DWORD dwTlsIndex);

当所有线程中不再需要保留TLS时隙的位置时,调用BOOL TlsFree(DWORD dwTlsIndex)告诉系统该时隙不再需要保留。

静态TLS:

静态TLS将数据和线程联系起来,只需要进行如下声明:

__declspec(thread) DWORD gt_dwStartTime=0;

__declspec(thread)告诉编译器,对应的变量应该放入可执行文件或DLL文件中自己的节中,后面的变量必声明为函数中(或函数外)的一个全局变量或静态变量。

线程本地存储器——Windows核心编程学习手札之二十一相关推荐

  1. 线程的堆栈——Windows核心编程学习手札之十六

    线程的堆栈 --Windows核心编程学习手札之十六 系统会在进程的地址空间内保存一些区域,同时也会在进程地址空间内为线程的堆栈保留区域.线程都有自己的堆栈,创建时,系统就保留一个堆栈空间区域,并将相 ...

  2. 线程基础知识——Windows核心编程学习手札系列之六

    线程基础知识 --Windows核心编程学习手札系列之六 线程与进程一样由两部分构成:一是线程的内核对象,操作系统用它来对线程实施管理,也是系统用来存放线程统计信息的地方:二是线程堆栈,用于维护线程在 ...

  3. 用户方式中线程的同步——Windows核心编程学习手札之八

    用户方式中线程的同步 --Windows核心编程学习手札之八 系统中所有线程都必须拥有对各种系统资源的访问权,这些资源包括内存堆栈.串口.文件.窗口和许多其他资源.如果一个线程需要独占对资源的访问权, ...

  4. 插入DLL和挂接API——Windows核心编程学习手札之二十二

    插入DLL和挂接API --Windows核心编程学习手札之二十二 如下情况,可能要打破进程的界限,访问另一个进程的地址空间: 1)为另一个进程创建的窗口建立子类时: 2)需要调试帮助时,如需要确定另 ...

  5. 窗口消息——Windows核心编程学习手札之二十六

    窗口消息 --Windows核心编程学习手札之二十六 Windows允许一个进程至多建立10000个不同类型的用户对象(user object):图符.光标.窗口类.菜单.加速键表等,当一个线程调用一 ...

  6. 未处理异常和C++异常——Windows核心编程学习手札之二十五

    未处理异常和C++异常 --Windows核心编程学习手札之二十五 当一个异常过滤器返回EXCEPTION_CONTINUE_SEARCH标识符时是告诉系统继续上溯调用树,寻找另外的异常过滤器,但当每 ...

  7. 异常处理程序和软件异常——Windows核心编程学习手札之二十四

    异常处理程序和软件异常 --Windows核心编程学习手札之二十四 CPU负责捕捉无效内存访问和用0除一个数值这种错误,并相应引发一个异常作为对错误的反应,CPU引发的异常称为硬件异常(hardwar ...

  8. 结束处理程序——Windows核心编程学习手札之二十三

    结束处理程序 --Windows核心编程学习手札之二十三 使用SEH可以只关注程序要完成任务,而运行中发生的错误,系统将会发现并通知.Windows引入SHE是为了便于操作系统的开发,使用SHE所造成 ...

  9. DLL的高级操作技术——Windows核心编程学习手札之二十

    DLL的高级操作技术 --Windows核心编程学习手札之二十 显示加载DLL模块: HINSTANCE LoadLibrary(PCTSTR pszDLLPathName); HINSTANCE L ...

最新文章

  1. 趁周末,来学点进阶知识:Java 动态编译
  2. Flyweight Pattern简单随笔
  3. Gradle语法基础解析
  4. signature=02d2eb69b4d24e2f9bb2956f66089339,Signature Balancing
  5. spring mvc学习(60):ssm项目整合
  6. 面试常考题---交换变量
  7. python中sys模块有问题_python中sys模块之输入输出错误流
  8. C++ - extern C用法浅析
  9. C语言和设计模式(桥接模式)
  10. eclipse的workspace和working set
  11. HDU 5773 The All-purpose Zero(O(nlgn)求LIS)
  12. UG二次开发-基础篇:GRIP函数查询表与帮助文档
  13. deamon守护线程
  14. 【解决思路】当前不会命中断点,还未为文档加载任何符号
  15. Echarts示例大全 Demo合集网站
  16. COIL:结合稠密检索和词汇匹配的更高效检索模型
  17. 中等职业学校计算机课程标准,全市中等职业学校信息技术课程标准内涵解析与教学设计培训会议成功举办...
  18. Access-Cookie注入
  19. 【问链财经-区块链基础知识系列】 第四十四课 邮储银行:U链福费廷业务系统
  20. 炸分王的省选2021(A)游记

热门文章

  1. uo和o的区别和用法_汉语拼音中,o与uo有什么区别
  2. linux 生成字母序列,Python序列之字符串
  3. php钩子函数示例,PHP中钩子函数的实现与认识
  4. python 输出字符串编码_Python print 字符串编码问题
  5. anaconda tensorflow 2.3_安装anaconda amp;源码安装lightgbm,xgboost
  6. js能订阅mq吗_高颜值宠物营养品订阅盒!除了好看,真的能补充营养吗?
  7. Session丢失的解决办法小结
  8. 插上翅膀,让Excel飞起来——xlwings(一)
  9. idea 自定义工具栏
  10. xunsearch: 开启后台服务,索引……随笔记录