【问题标题】:Can thread_local be used to provide a static global variable in a dll for each thread?thread_local 可以用于在 dll 中为每个线程提供静态全局变量吗?
【发布时间】:2015-11-09 04:09:39
【问题描述】:

我想在我们的开源库中使用 C++11 关键字 thread_local,它可以在许多平台(Windows、Linux、Mac OS 等)上动态或静态链接,在静态变量。这个变量是一个类类型,基本上只是封装了一个 std::stringstream 变量并对其进行初始化以适应我们的字符串流格式要求。出于性能原因,我们希望静态可用(有关更多详细信息,请参阅我以前的question),如果每个线程都这样做是可以的。

全局变量应该在静态模板类方法中使用,这些方法必须在头文件中实现。但这意味着,如果我理解正确,该库的用户可能会在其可执行文件的代码中包含此标头,这会将模板化方法编译到可执行文件中。然后,这些方法将从可执行文件的线程中访问提到的全局变量。我需要如何声明/定义静态变量才能使其工作,即我需要导出变量或类类型还是将其声明为“静态 thread_local X”就足够了?这是我目前的声明:

// SharedStringstream.h
#include <sstream>
// Export stands for _declspec(dllimport) or (dllexport) respectively
class EXPORT SharedStringstream
{
public:
    SharedStringstream();

    static thread_local SharedStringstream s_sharedStreamInstance;

    std::stringstream d_sharedStream;
};

以及定义:

// SharedStringstream.cpp
#include "SharedStringStream.h"

SharedStringstream SharedStringstream::s_sharedStreamInstance();

SharedStringstream::SharedStringstream()
{
    d_sharedStream.imbue(std::locale("C"));
    d_sharedStream << std::skipws;
    d_sharedStream >> std::skipws;
}

如果没有导出,我会收到链接器错误,因此我会在 Visual Studio 2015 中收到以下错误:

错误 C2492 'public: static SharedStringstream SharedStringstream::s_sharedStreamInstance': 具有线程存储持续时间的数据可能没有 dll 接口

here 提供了更多信息,该信息基本上表明可能无法导出 thread_local 变量。为此,我必须将它从类中移出到我的命名空间中,这是唯一的方法吗?

此外: "Thread Local Storage" 上的 MSDN 页面关于 thread_local 和 DLL 的内容如下:

使用 thread 属性可能会干扰 DLL 导入的延迟加载。

对于我们的库所包含的某些插件,我们确实在内部使用延迟加载 DLL,但不会对变量进行任何调用。但是,我假设用户可以延迟加载库,尽管我们不正式支持这一点。假设我们不支持库的延迟加载并且不在内部从任何延迟加载的 dll 中调用变量,我们是否能够确定这在任何情况下都不会成为问题?

在我的问题中有没有我没有考虑过的问题?

【问题讨论】:

  • 当你说'对于一个静态变量'时,你真的是指作为一个静态变量吗?如果不是,那是什么?
  • @EJP 我改写了,更好吗?我不知道该怎么说更好。如果还是看不懂,请提出建议。
  • 您找到解决问题的方法了吗?我问是因为我有同样的问题......
  • 感觉有点像xkcd漫画:上古智慧xkcd.com/979
  • @mattmilten 是的,只是我总是回复 :D 对于它的价值,我还没有遇到我们的 atm 设置的任何问题,也没有人抱怨。

标签: c++ c++11 dll


【解决方案1】:

当 dll 加载时,它使用自己的内存模型加载。因此,任何静态代码都不会在不同进程之间共享。

【讨论】:

  • 我不确定这如何回答我的问题。我重新表述了这个话题,以使我的意思更清楚。无论如何,您介意详细说明您的答案吗?
猜你喜欢
  • 1970-01-01
  • 2015-10-15
  • 1970-01-01
  • 2020-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-22
相关资源
最近更新 更多