1

给定本机代码(C/C++),有人可以解释线程本地存储吗?它只是一个允许线程控制自己变量的生命周期的技巧,还是编译器或硬件有一些隔离/保护措施?

底层平台重要吗?

此外,关于上述内容,普通 TLS 和“光纤安全”TLS 之间有什么区别?

抱歉,我用谷歌搜索,但我只能找到如何使用 TLS(我已经知道),而不是幕后的令人讨厌的细节。

4

2 回答 2

4

线程本地存储 (TLS) 由操作系统管理。内核中的每个线程对象都包含一个本地 TLS 插槽数组。在运行时,应用程序的代码可以调用TlsAlloc()它需要的每个 TLS 变量(例如声明为__thread或的变量__declspec(thread),取决于编译器),以将可用索引保留到 TLS 数组中。然后每个线程可以使用TlsGetValue()TlsSetValue()读取/写入存储在调用线程的 TLS 数组中的这些索引处的值。使用 TLS 完成后,应用程序可以调用TlsFree()以释放其保留的索引。

例如,在应用程序启动时,应用程序调用TlsAlloc()一次以保留 TLS 索引 0。在随后运行的每个线程中,任何给定线程都可以调用TlsSetValue()TLS 索引 0,并且该值将在本地为该特定线程存储,因此值存储在其他线程的 TLS 索引 0 不会受到影响。

有关详细信息,请参阅 MSDN:

线程本地存储

纤维在螺纹内部运行。因此,在同一个线程中运行的多个纤程将为该线程共享同一个 TLS 数组。如果一个纤程在 TLS 索引 0 处设置一个值,则在同一线程中运行的所有纤程都会受到影响。Fiber-Safe TLS 只是一种编译器优化,可防止纤程缓存任何 TLS 信息,以防纤程在其生命周期内从一个线程跳转到另一个线程。

于 2013-08-06T19:42:50.940 回答
0

快速回答:当线程启动时,GS 段寄存器指向该线程的(大部分未记录的)OS 数据结构。此数据结构的元素之一是 64 个 PVOID 元素的数组,TLS 函数使用它来存储多达 64 个 TLS 变量。

于 2013-08-08T00:24:41.477 回答