线程本地存储/ Windows

时间:2013-08-06 19:34:17

标签: windows multithreading winapi thread-local-storage

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

下层平台是否重要?

此外,普通TLS和“光纤安全”TLS之间的区别是什么?

抱歉,我用Google搜索了,但我能找到的就是如何使用TLS(我已经知道),但不是幕后的怪异细节。

2 个答案:

答案 0 :(得分:4)

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

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

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

Thread Local Storage

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

答案 1 :(得分:0)

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