线程本地存储

Posted

技术标签:

【中文标题】线程本地存储【英文标题】:Thread Local Storage 【发布时间】:2010-06-26 12:56:24 【问题描述】:

当您为插槽中的线程 A 分配一些 TLS 时,您可以从线程 B 访问同一个插槽吗?

它是内部同步的还是如何工作的?

【问题讨论】:

“插槽”是什么意思?根据定义,TLS 不能从其他线程访问。 @Konrad:有关插槽信息,请参阅 Thread.AllocateSlot 和 Thread.AllocateNamedDataSlot。 【参考方案1】:

不,线程本地存储的全部意义在于它是线程的本地 - 如果您在不同的线程中访问相同的插槽,您将获得 that 线程而不是另一个线程。

如果您需要在线程之间共享状态,请不要使用线程本地存储。

【讨论】:

但是具有 TLS 插槽的数组是全局的,我不确定我是否理解它是怎么回事?还是我弄错了…… @Tony - 在幕后,操作系统负责确保插槽指向不同线程的不同内存,如您选择的答案所示。即使 TLS 变量是全局变量,每个线程使用的实际值也是不同的。 @entropy:据我所知,是的。某处可能需要一些权限,但如果是这样,我不知道详细信息。【参考方案2】:

函数的局部变量对于运行该函数的每个线程都是唯一的。这可以在 TLS 的帮助下完成,如前所述,TLS 对于每个线程都是 local。 如果您想在线程之间共享一些数据,有多种选择,从使用全局或静态变量到内存映射文件等...如果您需要在线程之间共享数据,还请检查线程同步。

下图说明了 TLS 的工作原理。

更多详情请查看MSDN。

(来源:microsoft.com)

【讨论】:

是的,我明白了,但是你的索引变量是全局的......所以它们可以被多个线程访问?? 是的,全局或静态变量在多个线程之间共享。【参考方案3】:

该术语可能会令人困惑,因为“插槽”通常是对内存位置或单个位置的隐喻。使用 TLS,插槽只是线程私有存储中某个位置的“名称”。在 x86/x84 上没有真正的线程本地存储——所有内存都是全局的——因此系统会根据正在访问它的线程将 TLS 中的每个“插槽”映射到不同的实际内存位置。来自同一个线程对一个槽的请求会导致相同的内存位置 - 从不同线程访问同一个槽会导致不同的内存位置。

因为每个线程看到不同的数据,所以不需要同步。当然,除非您选择将同一个对象存储在两个不同线程的 TLS 中,否则情况就不同了,但这是相当人为的情况 - 共享不是因为 TLS。

【讨论】:

以上是关于线程本地存储的主要内容,如果未能解决你的问题,请参考以下文章

线程本地存储进程

线程本地存储及实现原理

Delphi 类变量是不是具有全局或线程本地存储?

如何释放线程本地存储的堆内存

C# 线程本地存储 调用上下文 逻辑调用上下文

什么是 Python 中的“线程本地存储”,为什么需要它?