thread_local 动态加载库中的静态变量——它们是什么时候创建的?

thread_local static variables in a dynamic loaded library – when are they created?

cppreferencethread_local 变量上声明以下内容

The storage for the object is allocated when the thread begins and deallocated when the thread ends. Each thread has its own instance of the object. Only objects declared thread_local have this storage duration.

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

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

上处理它

cppreference 所说的是转述的。 the standard 中的实际内容是

All variables declared with the thread_local keyword have thread storage duration. The storage for these entities lasts for the duration of the thread in which they are created. There is a distinct object or reference per thread, and use of the declared name refers to the entity associated with the current thread.

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

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

通过 dlopenLoadLibrary 动态加载库的支持是 compiler/platform 扩展,而不是语言的一部分。它与 thread_local 的交互方式也将因平台而异。