【问题标题】:thread_local static variables in a dynamic loaded library – when are they created?动态加载库中的 thread_local 静态变量——它们是什么时候创建的?
【发布时间】:2021-06-10 22:24:31
【问题描述】:

cppreferencethread_local 变量上声明以下内容

对象的存储在线程开始时分配,在线程结束时释放。每个线程都有自己的对象实例。只有声明为 thread_local 的对象才有此存储期限。

我想使用在共享库中声明的thread_local static 成员变量,该共享库在运行时通过dlopen / LoadLibrary 加载。由于完全有可能在加载该库的时间点已经有相当多的线程在运行,其中一些线程稍后将访问该变量,我想知道如果在线程开始时分配存储空间,这是如何工作的?如果在创建线程的时间点程序中不存在变量,这显然不能像那里解释的那样工作。此外,如果一个进程正在运行,这似乎是一种资源浪费。 100 个线程将为每个线程创建该线程局部变量的实例,前提是只有少数线程实际访问该变量。

那么,这里的文档是不正确的,还是我在这里尝试的可能会导致未定义的行为?如果文档完全不正确,我在哪里可以找到关于现实中可以预期的可靠描述?如果它是定义的实现,我特别感兴趣的是 clang 如何在 macOS 和 Windows 上处理它。

【问题讨论】:

    标签: c++ dynamic-loading thread-local-storage


    【解决方案1】:

    cppreference 所说的是意译。 the standard 中的实际内容是

    使用thread_local 关键字声明的所有变量都有线程存储持续时间。这些存储 实体在创建它们的线程中持续存在。有一个不同的对象或引用 每个线程,并且使用声明的名称是指与当前线程关联的实体。

    其中没有关于何时分配存储的确切信息,只是它在线程期间持续存在。这意味着它可以在创建线程时分配,或者在第一次使用变量时分配,或者可能是两者的组合。

    分配存储时,可能不会构造变量(我假设这就是您说“创建实例”时的意思)。这取决于变量的定义位置和方式。但是,如果它被构造,它不会被销毁,直到线程结束。

    支持通过dlopenLoadLibrary 动态加载库是编译器/平台扩展,而不是语言的一部分。它与thread_local 的交互方式也将是特定于平台的。

    【讨论】:

    猜你喜欢
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 2012-02-01
    • 2015-10-14
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多