【问题标题】:How to construct a static thread_local member with non-trivial constructor如何使用非平凡的构造函数构造静态 thread_local 成员
【发布时间】:2019-07-27 06:07:21
【问题描述】:

我有一个类成员,我想构建它应该是每个访问它的线程的本地成员。构造函数需要一些参数,所以我不能依赖静态零初始化。

class ThreadMem{
public:
    ThreadMem(uint32 cachelineSize, uint32 cachelineCount);
};    

class ThreadPool{
public:
    ThreadPool(uint32 cachelineSize, uint32 cachelineCount){
        // I need to prepare the `m_mem` in other threads with these arguments somehow
    }
    ThreadMem & mem() {
        return m_mem;
    }
private:
    static thread_local ThreadMem m_mem;
};

哪里是构造static thread_local ThreadMem ThreadPool::m_mem 的最佳位置,以便每个线程只构造一次,只有ThreadPool 的构造线程可以在运行时计算值?

【问题讨论】:

  • 就我个人而言,我发现只有一个返回对thread_local 的引用的static 成员函数更简单,就像Meyers' Singleton 的实现方式一样。它可以很容易地控制它们的初始化时间和方式。
  • @FrançoisAndrieux 这意味着每次使用静态函数调用该函数时,您都必须将参数传递给它的构造函数,对吧?
  • @MaximEgorushkin 是的,但您可以保留第一次调用时获得的参考。
  • 这对我来说似乎很奇怪。在 ThreadPool 中,顾名思义是一个线程池管理器,为什么它需要线程本地内存?为什么不将其构建到池线程中?
  • @user4581301 - 任何线程(工作线程和非工作线程)都可以创建作业或分配内存,因此每个线程都有一个池可以避免在分配时争用一个池

标签: c++ constructor static c++14 thread-local


【解决方案1】:

该静态类成员是由 C++ 运行时在动态初始化阶段在输入main 之前构造的。其构造函数的参数必须在那个时候可用,这可能是不可行的。

【讨论】:

  • 噢,真糟糕,它看起来确实不可行(我用来发现缓存线大小的库必须在那个阶段之后初始化)。在这种情况下,我将重新设计它以不使用 thread_local,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
  • 2014-05-08
  • 2018-10-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多