问题标签 [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.

0 投票
1 回答
394 浏览

c++ - 当协程切换线程时,如何强制 Linux 上的 g++ 更新线程指针(用于 TLS)?

我在 C++ 中使用自定义的协程实现(编译器 g++,在 ARM 上)。协程可能会通过调用 move_to_thread 函数(或其他方式,但这会让我明白我的观点)从一个线程迁移到另一个线程。我过于简单化了,但它有点像这样:

我遇到的问题是调用 move_to_thread 之前和之后完成的工作使用线程局部变量(使用__thread)。使用优化编译时,线程 2 上运行的代码仍然访问线程 1 的线程局部变量,而不是它自己的变量。这是因为对线程局部变量的访问会执行以下操作:

  1. 查找当前线程的 TLS 线程指针
  2. 将 x 的 TLS 偏移量添加到线程指针
  3. 将此地址的内存用作 x

但是,启用优化后,(1) 和可能 (2) 正在针对第二次访问进行优化,因为编译器假定开始在特定线程上运行的函数将保留在该线程上。这个假设不适用于我的代码。

如何让编译器在调用 move_to_thread 之前和之后查看正确的线程本地存储,而不完全取消优化?

0 投票
3 回答
4319 浏览

c - C中的线程本地数据

我最近一直在尝试线程本地存储。我有工作代码,一切似乎都很好,但是当我用 valgrind 运行我的程序时,看起来有一些问题。

我的问题是,如果我将内存分配给静态线程本地存储,它会在线程退出时被删除吗?

这是我的代码:

输出:

验证:

0 投票
0 回答
155 浏览

freepascal - 保存/恢复线程本地存储

我正在尝试在 FreePascal 中使用w32 光纤 API来实现协程类。到目前为止,我可以分配工作上下文 (CreateFiber) 并在上下文之间切换 (SwitchToFiber)。

但是我无法让异常可靠地工作。在不同的上下文中应该有不同的异常链。当使用 w32 SEH 异常处理链时,链切换会在 SwitchToFiber 中自动发生。但是 FreePascal 不使用 w32 SEH 链,而是将自己的链存储在 threadvar 中。

我想继续尝试手动保存/恢复线程变量。到目前为止,我可以获得 ThreadEnvironmentBlock 结构:

我相信线程变量存储在 ThreadLocalStorage 中,它位于 ThreadEnvironmentBlock 内的某个位置;-) 现在我想正确保存和恢复 ThreadLocalStorage。需要以下信息:

  1. ThreadEnvironmentBlock 线程变量存储在哪里?
  2. 如何将它们保存/存储到全局堆中/从全局堆中保存?
0 投票
1 回答
1524 浏览

c - OpenMP 和带有 icc 的线程本地存储标识符

这是一个简单的测试代码:

gcc编译这个没有任何问题,-fopenmp但抱怨icc (ICC) 12.0.2 20110112-openmp

test.c(7): error: "a" must be specified in a variable list at an enclosure OpenMP parallel pragma #pragma omp parallel default(none)

我不知道哪种范式(即shared, privatethreadprivate适用于这种类型的变量。哪一个是正确的使用?

调用访问该线程局部变量的函数时,我得到了预期的行为,但是我无法从显式并行部分中访问它。

编辑:

到目前为止,我最好的解决方案是通过函数返回指向变量的指针

0 投票
1 回答
838 浏览

c++ - 为什么 thread_local 的这种用法会崩溃?

我已将问题简化为以下小代码片段:

执行时程序崩溃。为什么?

我在 Windows 上使用 gcc 版本 4.8.2,我使用g++ -std=c++11 main.cpp.

0 投票
2 回答
2967 浏览

c++ - 多个动态链接库 (DLL) 是否可以从静态库 (LIB) 共享线程本地存储

我有一个由许多 DLL 文件组成的游戏。其中一些 DLL 链接到同一个静态库 (LIB)。

所以是这样的:

Root.dll 加载静态链接 Common.lib 的 Child.dll。Root 也静态链接 Common.lib。因为 Common 是静态链接的,所以它直接编译到加载的 dll 中(例如 Root 和 Child)。

Common.lib 包含一个使用线程本地存储 (TLS) 的变量。

这会导致一些有问题的行为:Root.dll 和 Child.dll 各自包含不同的 TLS 数据实例 (s_threadValues)。即使在同一个线程上,如果 Root.dll 调用 Common.lib 中定义的函数,则 s_threadValues 的值将与从 Child.dll 调用相同函数的值不同。

由于两个 DLL 都从同一个线程访问这个 TLS,我希望 TLS 是共享的,但事实并非如此。

现在,如果我将 Common.lib 更改为动态链接(例如 Common.dll),则不会再出现此问题 Root.dll 和 Child.dll 的 s_threadValues 相同。

这是预期的行为吗?无论如何在使用它的动态库之间共享静态库中定义的 TLS 共享?

0 投票
2 回答
8923 浏览

c++ - 线程特定数据与线程本地存储

我已经阅读了 Kerrisk 的The Linux Programming Interface: A Linux and UNIX System Programming Handbook,第 31 章关于线程。本章包括线程特定数据(第 31.3.4 节)和线程本地存储(第 31.4 节)。第 663-669 页涵盖了这些主题。

线程特定数据(pthread_key_createpthread_setspecificpthread_getspecific和朋友)看起来更强大,但似乎使用起来有点麻烦,并且似乎更频繁地使用内存管理器。

线程本地存储(__thread在静态和全局声明上)看起来不太强大,因为它受限于编译时间,但它似乎更易于使用,并且在运行时似乎远离内存管理器。

pthread_key_create我对运行时内存管理器的看法可能是错误的,因为当它遇到__thread变量时可能会有在后台调用的代码。

Kerrisk 没有提供两种策略的比较/对比,他也没有就在特定情况下何时使用哪种策略提出建议。

为问题添加上下文:我正在评估第 3 方库。该库使用全局变量,不使用锁定,我想在多线程程序中使用它。该程序使用线程来最小化网络延迟。

有没有一个不折不扣的赢家?或者是否有不同的场景需要使用其中一种?

0 投票
2 回答
1965 浏览

c# - 任务工厂和线程本地存储

我在一个循环中从任务工厂创建了 x 个任务。当我等待所有任务完成时,这些任务会开始并做一些工作。

我的问题是每个任务/线程都初始化自己的昂贵对象的副本,例如 DocumentObject。理想情况下,我希望为每个任务/线程重新使用这个对象,这样当它作为工厂的一部分重新使用时,就不需要重新创建了。

ThreadLocal.Net 中的概念是否可以实现类似的事情。

0 投票
1 回答
1204 浏览

java - thread local variables in clojure

  1. For no other reason than i have a lot of other custom libraries that i have written that run on 1.1.

I need a straight forward way to have thread local variables a lot of the method i have seen are incompatible with this version of clojure.

seen in this examples

e.g. (thread-local (atom 0)))

(def ^{:dynamic true} counter)

don't seem to work for me

So i just need to be pointed in the right direction.

0 投票
1 回答
565 浏览

c# - 使用 ThreadLocal 传递数据跨越不同的班级

在 usr 指出我的问题不清楚之后,用下面关于“另一个线程”的更多信息编辑了我的问题。

如何使用ThreadLocal<T>跨不同类传递数据?

基本上,我需要将 LogContext 信息从 Webservice 中的一个类传递给一个TraceExtension:SoapExtension类(TraceExtension 是记录此 WebService 调用的另一个 WebService 的请求/响应)。

由于该功能在另一个线程上运行,而不是在发起请求的线程上运行,因此我无法从ServiceContext:IExtension <InstanceContext> 通常用于此类事情的 a 中获取它。

我有一个使用这种Thread.GetNamedDataSlot()方式的工作实现,但在性能测试中我们发现存在内存泄漏问题。(是的,我已经打电话了Thread.FreeNamedDataSlot(),问题仍然存在)。这导致 MS 发布http://support.microsoft.com/kb/2540745可能存在泄漏问题,但在我们当前的发布时间范围内,不可能在所有生产服务器上部署修复程序。建议的解决方法是使用 System.Threading.ThreadLocal 类。

到目前为止,我发现的所有资源/示例都有同一类中的 ThreadLocal 实例以及 Parallelism 和 PLinq 实例。在一个类中初始化/设置数据并从另一个类中检索数据的示例将非常有帮助。将数据传递给的任何其他方式TraceExtension : SoapExtension也同样有帮助。

我们的日程安排有点紧,我们将不胜感激。

编辑更多信息:

发出请求的 Web 服务线程创建了一个新线程,我们在该线程上运行一些后台处理,同时返回必要的响应。新线程调用对其他后端 Web 服务的调用。我们还有一个 TraceExtension 类来跟踪后端 Web 服务的请求/响应。我们使用ContextInfo : ISynchronizeInvoke.

问题是从调用后端 web 服务调用的类中获取 LogContext 对象到 TraceExtension 类(它在新线程上运行,而不是在客户端请求所在的原始线程上运行,ServiceContext:IExtension<InstanceContext>它确实保存了 LogContext)