【问题标题】:When and how are thread_local variables initialized and destroyed?thread_local 变量何时以及如何初始化和销毁​​?
【发布时间】:2020-09-11 12:33:52
【问题描述】:

我想在我的代码中使用 thread_local 之前更好地理解它。

比方说,我声明

thread_local myclass value;

这将为每个使用value 的线程创建myclass 的新实例?线程退出时会发生什么?实例会被释放还是会保留在内存中的某个位置?什么时候调用析构函数?

thread_local 是否会锁定构造函数以便在任何时候都只能调用一个?

【问题讨论】:

    标签: c++ destructor thread-local


    【解决方案1】:

    [basic.stc.thread]/1所有使用thread_local 关键字声明的变量都有线程存储持续时间。这些实体的存储将持续到创建它们的线程的持续时间。每个线程都有一个不同的对象或引用,使用声明的名称是指与当前线程关联的实体。

    [basic.stc.thread]/2 具有线程存储持续时间的变量应在其首次使用 odr (6.2) 之前进行初始化,如果已构造,则应在线程退出时销毁。

    不,构造函数调用没有自动同步。不需要,因为只有一个线程可以尝试构造给定的线程本地对象。

    【讨论】:

    • 假设我声明了随机数生成器thread_local,它需要它的种子。如果初始化不同步,对于这种情况,我们可以有几个随机数生成器返回相同的数字序列
    • 即使初始化是同步的,也可能发生这种情况(事实并非如此,但让我们假装吧)。所需要的只是在同一秒内发生两个调用。如果这是您程序中的问题,您需要安排更好的播种机制;线程同步与此问题无关。
    • 您可以经常使用random_device 播种您的prng:thread_local std::mt19937 prng(std::random_device{}());
    【解决方案2】:

    根据this storage duration reference一个thread_local变量:

    ...在线程开始时分配,在线程结束时释放。

    所以是的,当线程结束时,该线程的thread_local 变量的生命周期也结束了,这意味着这些特定实例将被破坏。

    【讨论】:

      猜你喜欢
      • 2017-09-11
      • 1970-01-01
      • 1970-01-01
      • 2015-08-19
      • 2014-08-06
      • 2015-07-18
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多