C++编译器如何在C++ 0x中实现线程本地存储?

Yun*_*ncy 13 c++ thread-local thread-local-storage c++11

c ++编译器如何在C++ 0x中实现线程本地存储

我在谷歌搜索过这个.但我找不到任何关于此事的内容.

有没有人对此有任何材料?

Dou*_*oug 17

阅读维基百科条目.

线程本地存储不是C++特有的.有时它会有不同的名称,例如"TLS"(只是线程本地存储的缩写)或"线程专用存储"(TSS).

大多数操作系统都提供API来访问每线程存储.例如,Windows有一堆以"TLS"开头的API函数.在引擎盖下,Win32为各种线程数据保留了一个特殊区域,包括用户线程本地存储,可通过特定的CPU寄存器(x86上的FS)访问.Linux通过pthread API提供特定于线程的存储,其名称类似于pthread_key_create,这些通常使用类似的技术实现.

操作系统可能根本不提供任何支持.但是,如果操作系统通过API提供进程唯一的线程ID,那么C++运行时库可以在概念上维护std::map<thread_id, per_thread_storage>内部的内容.当然,那就是问题所在per_thread_storage.如果程序是静态链接的,它可能就像指向一个大结构的指针,所有的线程局部存储变量都在程序中声明为元素.这是一个过于简单化,但你得到了一般的想法.

访问线程本地存储变量显然不仅仅是直接读取或写入内存.它可能比这更具参与性.如果要在特定函数中大量使用线程本地/特定存储,我建议您先将线程局部存储指针复制到局部变量中.

  • @doron:编译器和加载器要么使用操作系统提供的API,要么他们自己做一些等同于映射技术的东西,而不需要应用程序员编写任何代码. (6认同)
  • 您已经回答了应用程序开发人员如何实现TLS,而不是编译器和加载程序如何处理C++ 0x thread_local关键字 (2认同)

dor*_*ron 6

全局变量(或可写静态数据-WSD)通常存储在与堆栈,堆和代码分开的存储块中。在可执行文件的代码开始运行之前,将创建并初始化WSD块。

C ++ 0x引入了thread_local关键字,该关键字可确保为每个线程创建全局变量的单独实例。问题是每个线程需要加载一个不同的块。

下一个困难是变量的地址在链接时不固定,并且对于每个线程都是不同的。

解决这个问题有两种方法。一种是让编译器生成函数调用以获得正确的块,而另一种是更改ABI以将TLS块存储在处理器寄存器之一中。然后可以将其与偏移量一起使用以访问正确的thread_local变量。

这与库支持不同,在库支持中,操作系统存储单个void*值,该值可用于存储指向已在进程堆上分配的线程本地块的指针。

如果您需要血腥细节,请点击此处