问题标签 [thread-local-storage]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - __thread 上的夹板 barfs,它是 C99 的一部分
跑步夹板
在这条线上暂停:
出现解析错误:
检查文档和漱口水没有提到__thread
. 然而,它是 Splint 据称支持__thread
的 C99 规范的一部分(插入参考)。
这里发生了什么?我怎样才能让夹板识别__thread
?
c++ - 使用线程局部存储将具有全局变量的单线程遗留代码转换为多线程代码
我有一个遗留 C/C++ 代码的代码库,其中包含许多访问全局静态变量的函数,因此不是线程安全的。我正在寻找有关如何转换此代码以使其线程安全的建议。我突然想到,一种方法是将静态变量转换为线程局部变量,或者将它们存储在线程局部存储中。这样做的好处是我不必重写大量使用函数向它们传递额外上下文的代码,只需重写线程不安全函数本身。但是在研究这一点时,我没有找到很多关于这是一个好主意还是坏主意的建议。我有一些具体的担忧是
- 访问基于 TLS 的数据会显着变慢吗?
- 我只是继续陷入使用全局变量的陷阱,因为“全局变量不好”,还是 TLS 抵消了 global-variables-are-bad 论点?
任何其他想法也将不胜感激。
c++ - C++ 编译器如何在 C++0x 中实现线程本地存储?
c++编译器如何在C++0x中实现线程本地存储
我在谷歌搜索过这个。但我找不到任何关于此的信息。
有人有这方面的资料吗??
.net - log4net.ThreadContext 和 log4net.LogicalThreadContext 有什么区别?
2014 年 11 月 18 日更新 - 在浏览 log4net 源存储库时,我发现 LogicalThreadContext 的实现在 2011 年 11 月被修改为它使用 CallContext.LogicalSetData 存储其属性(并使用 LogicalGetData 获取它们)。这很重要,因为这意味着 LogicalThreadContext 现在应该可以正常工作。存储在 LogicalThreadContext 中的任何数据都应该“流向”任何子线程或任务。这与 ThreadContext(以及 LogicalThreadContext 的旧实现)相比,其中存储在上下文中的数据将保持在当前线程的本地,并且不会流向子线程/任务。
如果你有兴趣,这里是变化:
希望遇到这个老问题的人会发现这些信息很有用。
log4net 提供了两个不同的“线程上下文”对象: ThreadContext和LogicalThreadContext,每个对象都有一个属性包,Properties。ThreadContext 有一个ThreadContextProperties包,而 LogicalThreadContext 有一个LogicalThreadContextProperties包。
ThreadContext 可能更常被称为“MDC”。LogicalContext 可能更常被称为“LDC”。我将在这篇文章的其余部分使用简称。
MDC.Properties 使用System.Threading.Thread.SetData实现,而 LDC.Properties 使用System.Runtime.Remoting.Messaging.CallContext.SetData实现。
为了比较,NLog 只公开“MDC”(现在称为 MappedDiagnosticContext)来存储线程本地属性。NLog的实现使用System.Threading.Thread.SetData,所以它的实现和log4net的一样。
在 log4net 和 NLog 中,“MDC”属性都存储在字典中,而字典本身存储在线程本地存储中。
在这种情况下,将字典存储在用 [ThreadStatic] 修饰的类成员变量中是否等效?
使用 .NET 4.0 的新 ThreadLocal 类的等效(或类似)声明是什么?
最终,LDC 和 MDC 之间真正的、实际的区别是什么?即使在阅读了上面链接的 MSDN 主题之后,我也不清楚。你什么时候真的会使用其中一个?似乎我在 log4net 和上下文中看到的绝大多数参考/示例都是针对 GDC(全局 - 我理解)、NDC(嵌套 - 我也理解)和 MDC。我在谷歌搜索时可以找到的大多数 LDC(或 LogicalThreadContext)参考资料都与签入 log4net 源代码存储库有关,而不是实际使用。LDC 几乎从不提出问题或示例。
我确实发现这个链接提供了一些关于与 log4net 开发人员之一 Nicko Cadell 的区别的非常好的信息,但我仍然不清楚。
与 log4net 没有直接关系的一个更大的问题是 Thread.SetData 和 CallContext.SetData 之间的实际区别是什么?
根据CallContext MSDN 文章,CallContext 数据可以传播到另一个 AppDomain。要传播,存储在 CallContext 中的数据项必须公开ILogicalThreadAffinative接口。所以,这似乎是 Thread.SetData 和 CallContext 之间的区别之一。
根据 Nicko Cadell 链接,log4net 没有实现 ILogicalThreadAffinative,因此不会传播 LDC 属性。
也许这里有足够的东西我应该能够回答我自己的问题,也许不是。我仍在努力理解。
如果你使用 log4net,你每个人都使用 MDC、LDC 吗?如果你使用 MDC,是不是因为大多数“现实世界”的例子似乎都在使用它?如果您使用 LDC,您有使用它的具体原因吗?如果你同时使用,你如何选择何时使用哪个?
请注意,我看过一些关于 MDC(可能是 LDC)的文章,由于线程切换,可能无法在 ASP.net 应用程序中正常工作。我对这个问题不是特别感兴趣,因为我不在 ASP.net 中工作。
实际上,我在这里找到了一些关于 SO 的有用帖子,它们可能有助于讨论:
提前致谢!
multithreading - 如何使用 g++ 在 64 位 solaris sparc 上编译线程本地存储 (TLS)
我有一段 C/C++ 代码,它使用 __thread 关键字进行线程本地存储,但是在使用 g++(版本 4.0.2)的 64 位 Solaris Sparc 上编译它时遇到问题,而它在使用 g++ 的 Linux 上编译和运行正常34 编译器。下面是一个源代码示例:
来自“g++ -dumpversion”命令的编译器信息返回“4.0.2”,“g++ -dumpmachine”显示“sparc-sun-solaris2.8”。“uname -a”显示“SunOS devsol1 5.9 Generic_118558-26 sun4u sparc SUNW,UltraAX-i2”。
使用 g++ 运行 make 时的错误消息是:“错误:此目标不支持线程本地存储”,我使用的编译器选项是
非常感谢任何帮助,因为我在周末一直在努力解决这个问题并且面临最后期限。
谢谢,查尔斯
linux - ELF 文件 TLS 和 LOAD 程序部分
-static
编译后readelf -l
显示来自精灵的程序头:
有人可以解释一下,为什么第二个和第四个程序头确实相交(它们以相同的偏移量 0x079f94 和 VirtAddr 0x080c2f94 开头)。
此外,段部分.tdata
被引用两次。
第一个线程(程序本身)如何PT_TLS
以及将如何加载?存在于记忆的什么PT_LOAD
地方?.tbss
c++ - 从另一个线程访问线程本地
如何从另一个线程读取/写入线程局部变量?也就是说,在Thread AI 中想访问Thread B 的线程本地存储区中的变量。我知道另一个线程的 ID。
该变量__thread
在 GCC 中声明。目标平台是 Linux,但独立性可能很好(但是 GCC 特定的也可以)。
缺少线程启动钩子,我无法在每个线程的开始处简单地跟踪这个值。需要以这种方式跟踪所有线程(不仅仅是特别启动的线程)。
像 boost thread_local_storage 或使用 pthread 键这样的更高级别的包装器不是一种选择。我需要使用真正的__thread
局部变量的性能。
第一个答案是错误的:不能将全局变量用于我想做的事情。每个线程都必须有自己的变量副本。此外,出于性能原因,这些变量必须是__thread
变量(同样有效的解决方案也可以,但我不知道)。我也不控制线程入口点,因此这些线程不可能注册任何类型的结构。
Thread Local is not private:关于线程局部变量的另一个误解。这些绝不是线程的某种私有变量。它们是全局可寻址内存,其限制是它们的生命周期与线程相关。如果给定指向这些变量的指针,则来自任何线程的任何函数都可以修改它们。上面的问题本质上是关于如何获取该指针地址。
c - 线程本地存储开销
假设有一些使用全局变量的不可重入函数:
然后,我想在多线程代码中使用这个函数,所以我可以这样改变代码:
或者,通过使用 gcc __thread 说明符,更简单:
最后一个的优点是我不需要更改另一个调用 foo() 的代码。
我的问题是,线程本地存储的开销是多少?TLS有一些不明显的问题吗?
如果我将通过单独的指针修改 TLS`ed 变量,是否会有一些开销,如下所示:
谢谢。
c# - 访问线程本地存储
当第二个线程执行时,它会导致异常。你能解释一下为什么吗?
异常详情:
at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
at System.LocalDataStoreMgr.AllocateNamedDataSlot(String name)
at ConsoleApplication2.TLS.Run() in AutoLock.cs:line 65
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
谢谢。
c++ - 如何分配线程本地存储?
我的函数中有一个静态变量,但我希望它在每个线程的基础上都是静态的。
如何为我的 C++ 类分配内存,以便每个线程都有自己的类实例副本?
这是在 Linux 上。我没有使用 C++0x,这是 gcc v3.4.6。