动态加载库中的thread_local静态变量–它们是何时创建的



cppreference在thread_local变量上声明以下内容

对象的存储在线程开始时分配,在线程结束时解除分配。每个线程都有自己的对象实例。只有声明为thread_local的对象才具有此存储持续时间。

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

那么,这里的文档是否不正确,或者我在这里尝试的内容是否有可能导致未定义的行为?如果文档根本不正确,我在哪里可以找到对现实中预期内容的可靠描述?如果它是由实现定义的,我特别感兴趣的是clang如何在macOS和Windows上处理它。

cpprreference所说的是转述的。标准中实际包含的是

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

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

在分配存储时,变量可能不会被构造(我认为这就是您所说的"创建实例"的意思(。这取决于变量的定义位置和方式。但是,如果构建了它,那么在线程结束之前,它不会被破坏。

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

最新更新