Windows中的内核模式驱动程序是否存在线程局部存储(TLS)等效(确切地说是Win32)?
我试图实现的目标:
最终,在我的驱动程序的调度程序中,它可能会调用许多其他函数(可能存在深度调用).我想提供一些特定于正在处理的请求的上下文信息.也就是说,我有一些结构,指针应该在所有被调用的函数中都可见,而不是将它作为参数显式传递给每个函数.
使用static/global不是一个完美的选择(多线程,同步对象等).
如果那是用户模式代码 - 在这种情况下显然会使用TLS.但是AFAIK没有像TlsGetValue/ 这样的内核模式功能TlsSetValue.这是有道理的 - 要使这些功能工作,必须首先分配一个进程范围的TLS索引.OTOH驱动程序代码可以在任意线程上调用,不限于特定进程.
但是,我实际上并不需要持久的特定于线程的存储.我只需要一个特定于线程的存储来进行顶级函数调用.
我想我知道如何以一种黑客的方式"实施"TLS.我将始终使用预定义的索引(例如,index = 0),而不是分配TLS索引.在顶级函数中,我将保存存储的TLS值,并用所需的值覆盖它.完成后,将恢复保存的值.
幸运的是我知道如何在Win32中实现TLS.TIB每个线程都有一个结构(线程信息块).在每个线程中,可以使用FS:[18h]选择器访问它.在TIB包含(除其他外)通过TLS使用的阵列.其余的非常简单.
但是,我更愿意使用官方API来实现类似的功能.
提前致谢.
PS One理论上可以使用SEH(也存储每线程信息).也就是说,包装顶级代码__try/__except,然后在需要上下文信息的地方 - 用一些参数引发可持续异常,在__except块中用上下文信息填充参数,然后恢复执行.这是一个100%有效的程序流程,不使用未记录的功能.但对我来说这似乎是一个丑陋的黑客,更不用说性能并发症了.
可能重复:
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;
当我编译它时,我得到一个错误
error: ‘myClass::minInt’ is thread-local and so cannot be dynamically initialized
如何正确地做到这一点?
PS:gcc版本:4.6.3
Ulrich Drepper关于线程本地存储的论文概述了几种不同cpu架构的TLS ABI,但我发现它不足以作为实现TLS的基础,原因有两个:
例如,i386唯一的实际ABI要求是:
%gs:0 指向指向自身的指针.___tls_get_addr并且__tls_get_addr函数必须以正确的语义存在,以便查找任意TLS段.特别是,DTV的存在或布局不是 ABI的一部分,也不是主程序之外的TLS段的排序/布局.
似乎任何使用"TLS变体II"的拱门都具有大致上述ABI要求.但我完全不了解"TLS变体I"的要求,而且从阅读来源(在uClibc和glibc中)看来,甚至可能存在"变体I"的几种变体.
有没有更好的文件我应该看一下,或者熟悉TLS工作的人能向我解释ABI的要求吗?
我的问题是为什么在线程函数中使用TLS机制而不仅仅是局部变量?能否请您提供一些很好的例子,或者TLS优于本地变量的优势是什么?谢谢Mateusz
我面临着大量多线程应用程序的大量崩溃.
阅读这些关于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
我正在研究如何在Linux系统上实现TLS(线程本地存储).文档ELF处理线程局部存储解释了程序对线程局部变量的要求如何在ELF二进制文件中编码,以及"运行时"如何处理这些二进制文件.
但是,我不清楚在实践中,设置TLS区域的"运行时"是Linux内核(及其加载ELF二进制文件的代码)还是libc中的一些初始化代码.有人能简单解释一下吗
(背景:我正在尝试静态链接并运行一个应用程序,但它在启动时会出现段错误.在gdb中,我可以看到segfaulting代码是来自libc的一些初始化代码.它试图使用相对于的地址读取静态变量GS,但GS为零.)
这段代码:
#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 …有没有办法在.NET中确定线程本地存储占用的内存量?
具体来说,我希望找到ThreadStatic对象使用的内存量以及分配给Thread数据槽中对象的内存(例如,通过调用Thread.SetData).
澄清:
线程本地存储:http: //msdn.microsoft.com/en-us/library/6sby1byh.aspx
线程本地存储:螺纹相对静态字段和数据时隙 http://msdn.microsoft.com/en-us/library/6sby1byh.aspx
我pthread_getspecific在一个设计用于链接到各种iOS应用程序的库中显然出现错误结果时遇到了一些问题.
我看到Apple写道:
Cocoa和POSIX以不同的方式存储线程字典,因此您无法混合和匹配对这两种技术的调用.但是,只要您在线程代码中坚持使用一种技术,最终结果应该是相似的.在Cocoa中,您使用NSThread对象的threadDictionary方法来检索NSMutableDictionary对象,您可以向该对象添加线程所需的任何键.在POSIX中,您使用pthread_setspecific和pthread_getspecific函数来设置和获取线程的键和值.
这是否意味着,无论可可也不POSIX TLS功能可以预计在库代码工作的时候,我们不知道,我们调用的代码是否已经使用一个或其他?
在这些情况下,如何稳健地存储和检索线程局部指针?
是否有我们应该使用的本机Darwin TLS支持API而不是Cocoa或POSIX?
有没有办法在Linux上查询共享库的TLS模型?(例如使用ldd或其他工具).
我在使用"initial-exec"模型加载太多库时遇到了麻烦,并且想确定哪个第三方库使用此模型(因此我可以释放一些插槽,例如通过静态链接).
这会导致错误:
 dlopen: cannot load any more object with static TLS
看到这个问题.