【问题标题】:C++11: Nontrivial Thread Local Static Variable?C++11:非平凡线程局部静态变量?
【发布时间】:2012-08-16 10:59:52
【问题描述】:

我有一个 X 课:

class X { ... }

我想这样做:

void f()
{
    thread_local static X x = ...;

    ...
}

(其实我用的是gcc所以关键字是“__thread”)

但我不能,因为你只能拥有微不足道的 thread_locals。

最好的解决方法是什么?

如果我这样做:

void f()
{
    thread_local static X* p = 0;

    if (!p)
       p = new X(...);

    X& x = *p;

    ...
}

然后:

  1. 线程退出时不会调用析构函数
  2. 不必要的动态内存分配。

更新:

这是我目前所拥有的:

#include <iostream>
#include <type_traits>

using namespace std;

class X { public: X() { cout << "X::X()" << endl; }; ~X() { cout << "X::~X()" << endl; } };

void f()
{
        static __thread bool x_allocated = false;
        static __thread aligned_storage<sizeof(X),
             alignment_of<X>::value>::type x_storage;

        if (!x_allocated)
        {
                new (&x_storage) X;
                x_allocated = true;
                // add thread cleanup that calls destructor
        }

        X& x = *((X*) &x_storage);
}

int main()
{
        f();
}

这解决了动态内存分配问题。我只需要添加线程清理处理程序。有没有一种机制可以用 pthreads 做到这一点?

【问题讨论】:

  • 为什么你只能有微不足道的线程局部变量?标准杆?
  • 我是这么认为的? GCC 似乎不喜欢它。
  • @ForEveR 我认为标准没有这样的限制,而且GCC还没有实现C++11线程本地存储。
  • 这是一个 gcc 扩展,而不是 C++11 thread_local。见here。因此,无论何时实施,您都不会遇到琐碎问题。

标签: c++ multithreading c++11 thread-local thread-local-storage


【解决方案1】:

标准将thread_local 描述为与第7.1.1 节中的其他说明符(staticextern 等)一样的存储说明符。该词的任何定义都没有限制“简单”数据类型。

pre-C++11 discussion document N2147 中简要讨论了该问题(请参阅“线程变量动态初始化”部分)。这包括对正确实施所涉及的关键问题的描述。显然 GCC 实现 (static __thread) 还没有解决这些问题(这与 GCC 不正式支持 C++11 thread_local 的事实是一致的)。

另一种选择是boost::thread_specfic_ptr&lt;&gt; 提及in this earlier post 并描述here

另一种选择是使用std::thread 对象来实现线程并确保每个实例都维护自己的变量副本,可能包含在unique_ptr 中。

【讨论】:

  • 我需要稍微改变我的问题(也许需要发布新问题)。在我的环境中,使用 boost 或 std::thread 不是一个选项。我已经修复了动态分配问题(请参阅我的更新),但是我仍然需要一种在线程退出时调用析构函数的方法。有没有办法用 pthreads 做到这一点? (我意识到这现在是一个 gcc 特定问题)
  • 我会发布新问题,这样更容易。
【解决方案2】:

thread_local__thread 实际上不是一回事。它们之间的主要区别正是您偶然发现的那个-thread_local 允许变量为非 POD。不幸的是,这也有性能影响。有关这些性能影响的更多详细信息,请参阅this question

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 2015-10-15
    • 2018-08-05
    • 1970-01-01
    相关资源
    最近更新 更多