标签: thread-local-storage

内核模式下的线程本地存储?

Windows中的内核模式驱动程序是否存在线程局部存储(TLS)等效(确切地说是Win32)?

我试图实现的目标:

最终,在我的驱动程序的调度程序中,它可能会调用许多其他函数(可能存在深度调用).我想提供一些特定于正在处理的请求的上下文信息.也就是说,我有一些结构,指针应该在所有被调用的函数中都可见,而不是将它作为参数显式传递给每个函数.

使用static/global不是一个完美的选择(多线程,同步对象等).

如果那是用户模式代码 - 在这种情况下显然会使用TLS.但是AFAIK没有像TlsGetValue/ 这样的内核模式功能TlsSetValue.这是有道理的 - 要使这些功能工作,必须首先分配一个进程范围的TLS索引.OTOH驱动程序代码可以在任意线程上调用,不限于特定进程.

但是,我实际上并不需要持久的特定于线程的存储.我只需要一个特定于线程的存储来进行顶级函数调用.

我想我知道如何以一种黑客的方式"实施"TLS.我将始终使用预定义的索引(例如,index = 0),而不是分配TLS索引.在顶级函数中,我将保存存储的TLS值,并用所需的值覆盖它.完成后,将恢复保存的值.

幸运的是我知道如何在Win32中实现TLS.TIB每个线程都有一个结构(线程信息块).在每个线程中,可以使用FS:[18h]选择器访问它.在TIB包含(除其他外)通过TLS使用的阵列.其余的非常简单.

但是,我更愿意使用官方API来实现类似的功能.

  • 是否有官方的内核模式API来实现我的需求?
  • 有理由避免我打算做的事吗?我知道重新进入可能存在问题(即一些代码调用我,我覆盖TLS值,然后最终调用原始代码,这可能依赖于TLS).但在我的具体情况下,这是不可能的?
  • 有没有那么脏的方法来解决这个问题?

提前致谢.

PS One理论上可以使用SEH(也存储每线程信息).也就是说,包装顶级代码__try/__except,然后在需要上下文信息的地方 - 用一些参数引发可持续异常,在__except块中用上下文信息填充参数,然后恢复执行.这是一个100%有效的程序流程,不使用未记录的功能.但对我来说这似乎是一个丑陋的黑客,更不用说性能并发症了.

windows winapi kernel thread-local-storage

9
推荐指数
2
解决办法
2719
查看次数

如何在c ++中初始化线程局部变量?

可能重复:
gcc中的C++ 11 thread_local - 替代方法
有没有办法使用GCC的__thread完全模拟thread_local?

我想使用c ++ 11 thread_local来创建和使用thread_local变量,但由于gcc尚不支持,我使用的是gcc特有的__thread.我声明变量的方式是

myClass
{
public:

  static __thread int64_t m_minInt;

};
__thread int64_t myClass::m_minInt = 100;
Run Code Online (Sandbox Code Playgroud)

当我编译它时,我得到一个错误

error: ‘myClass::minInt’ is thread-local and so cannot be dynamically initialized
Run Code Online (Sandbox Code Playgroud)

如何正确地做到这一点?

PS:gcc版本:4.6.3

c++ multithreading gcc thread-local thread-local-storage

9
推荐指数
1
解决办法
8946
查看次数

每个cpu arch的真正ELF TLS ABI要求是什么?

Ulrich Drepper关于线程本地存储的论文概述了几种不同cpu架构的TLS ABI,但我发现它不足以作为实现TLS的基础,原因有两个:

  1. 它省略了许多重要的拱门,如ARM,MIPS等(虽然包括一堆与Itanium完全无关的)
  2. 更重要的是,它将大量实现细节与ABI混合在一起,因此很难说出互操作性需要哪些属性,哪些只是其实现的一部分.

例如,i386唯一的实际ABI要求是:

  • %gs:0 指向指向自身的指针.
  • 主可执行文件的TLS段(如果有)必须位于此地址的固定(通过链接器,负)偏移量.
  • 初始加载的库的所有其他TLS段必须具有相对于此地址的运行时常量(即,对于每个线程相同,但在不同的程序运行中不一定相同)(并且动态链接器必须能够填充重定位)这些补偿).
  • ___tls_get_addr并且__tls_get_addr函数必须以正确的语义存在,以便查找任意TLS段.

特别是,DTV的存在或布局不是 ABI的一部分,也不是主程序之外的TLS段的排序/布局.

似乎任何使用"TLS变体II"的拱门都具有大致上述ABI要求.但我完全不了解"TLS变体I"的要求,而且从阅读来源(在uClibc和glibc中)看来,甚至可能存在"变体I"的几种变体.

有没有更好的文件我应该看一下,或者熟悉TLS工作的人能向我解释ABI的要求吗?

c linux elf abi thread-local-storage

9
推荐指数
1
解决办法
960
查看次数

为什么要使用线程本地存储(TlsAlloc,TlsGetValue,ets)而不是局部变量

我的问题是为什么在线程函数中使用TLS机制而不仅仅是局部变量?能否请您提供一些很好的例子,或者TLS优于本地变量的优势是什么?谢谢Mateusz

storage multithreading local thread-local-storage

8
推荐指数
3
解决办法
5788
查看次数

是CWnd :: GetSafeHwnd()和CWnd :: m_hWnd ThreadSafe?

我面临着大量多线程应用程序的大量崩溃.

阅读这些关于TLS的 MSDN 页面,技术说明本文,我已经了解到CWnd对象在TLS中映射到HWND,这是一个线程依赖的内存访问.

我打算将看起来像CWnd线程远程访问的所有东西分离,然后将其转换为HWND引用,然后使用:: PostMessage作为通信端口.(就目前的代码而言,它代表了大量的工作,我现在正在制定解决方案,这需要花费很多时间,所以我们不得不讨论它).

但是我的一位同事真的非常坚持我只是将CWnd*保留在外国人线程中,采用:: PostMessage策略确定,但在外部线程中使用CWnd :: GetSafeHwnd()或pMyCWnd-> m_hWnd以便恢复原生HWND.

我一直认为,无处我已经看到GetSafeHwnd()是线程安全的,并且CWnd的Objet公司在TLS是,它在另一个线程值是不同的.我错了 ?MSDN显然使用术语"意外结果".

您的观点是什么,在创建者线程的外部线程中调用CWnd :: GetSafehwnd()或pMyCWnd-> m_hWnd?

您是否有任何MSDN文档说明这是否安全.

c++ winapi multithreading thread-safety thread-local-storage

8
推荐指数
2
解决办法
7455
查看次数

在Linux上,是由内核还是由libc(或其他语言运行库)设置的TLS?

我正在研究如何在Linux系统上实现TLS(线程本地存储).文档ELF处理线程局部存储解释了程序对线程局部变量的要求如何在ELF二进制文件中编码,以及"运行时"如何处理这些二进制文件.

但是,我不清楚在实践中,设置TLS区域的"运行时"是Linux内核(及其加载ELF二进制文件的代码)还是libc中的一些初始化代码.有人能简单解释一下吗

(背景:我正在尝试静态链接并运行一个应用程序,但它在启动时会出现段错误.在gdb中,我可以看到segfaulting代码是来自libc的一些初始化代码.它试图使用相对于的地址读取静态变量GS,但GS为零.)

c linux libc thread-local-storage

8
推荐指数
1
解决办法
1452
查看次数

C++为什么静态thread_local对象构造了两次?

这段代码:

#include <iostream>
#include <thread>
#include <mutex>

struct Singl{
    Singl(Singl const&) = delete;
    Singl(Singl&&) = delete;

    inline static thread_local bool alive = true;

    Singl(){
        std::cout << "Singl() " << std::this_thread::get_id() << std::endl;
    }
    ~Singl(){
        std::cout << "~Singl() " << std::this_thread::get_id() << std::endl;
        alive = false;
    }
};

static auto& singl(){
    static thread_local Singl i;
    return i;
}

struct URef{
    ~URef(){
        const bool alive = singl().alive;
        std::cout << alive << std::endl;
    }
};


int main() {
    std::thread([](){
        singl();
        static thread_local URef …
Run Code Online (Sandbox Code Playgroud)

c++ gcc thread-safety thread-local-storage mingw-w64

8
推荐指数
1
解决办法
510
查看次数

线程本地存储内存使用

有没有办法在.NET中确定线程本地存储占用的内存量?

具体来说,我希望找到ThreadStatic对象使用的内存量以及分配给Thread数据槽中对象的内存(例如,通过调用Thread.SetData).

澄清:

线程本地存储:http: //msdn.microsoft.com/en-us/library/6sby1byh.aspx

线程本地存储:螺纹相对静态字段和数据时隙 http://msdn.microsoft.com/en-us/library/6sby1byh.aspx

c# thread-local-storage

7
推荐指数
1
解决办法
2591
查看次数

如何在iOS中进行强大的线程本地存储

pthread_getspecific在一个设计用于链接到各种iOS应用程序的库中显然出现错误结果时遇到了一些问题.

我看到Apple写道:

Cocoa和POSIX以不同的方式存储线程字典,因此您无法混合和匹配对这两种技术的调用.但是,只要您在线程代码中坚持使用一种技术,最终结果应该是相似的.在Cocoa中,您使用NSThread对象的threadDictionary方法来检索NSMutableDictionary对象,您可以向该对象添加线程所需的任何键.在POSIX中,您使用pthread_setspecific和pthread_getspecific函数来设置和获取线程的键和值.

这是否意味着,无论可可也不POSIX TLS功能可以预计在库代码工作的时候,我们不知道,我们调用的代码是否已经使用一个或其他?

在这些情况下,如何稳健地存储和检索线程局部指针?

是否有我们应该使用的本机Darwin TLS支持API而不是Cocoa或POSIX?

c cocoa-touch pthreads thread-local-storage ios

7
推荐指数
1
解决办法
2430
查看次数

有没有办法确定Linux上的库使用的线程本地存储模型

有没有办法在Linux上查询共享库的TLS模型?(例如使用ldd或其他工具).

我在使用"initial-exec"模型加载太多库时遇到了麻烦,并且想确定哪个第三方库使用此模型(因此我可以释放一些插槽,例如通过静态链接).

这会导致错误:

 dlopen: cannot load any more object with static TLS
Run Code Online (Sandbox Code Playgroud)

看到这个问题.

linux glibc shared-libraries thread-local-storage ldd

7
推荐指数
1
解决办法
3599
查看次数