multithreading - C++11 中的动态 TLS

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

我正在编写一个 C++11 类 Foo,我想为每个实例提供自己的 Bar 类型的线程本地存储。也就是说,我希望每个线程和每个 Foo 实例分配一个 Bar。

如果我使用 pthreads,Foo 将有一个类型为 pthread_key_t 的非静态成员,Foo 的构造函数将使用 pthread_key_create() 进行初始化,而 Foo 的析构函数将使用 pthread_key_delete() 释放。或者,如果我只为 Microsoft Windows 编写代码,我可以用 TlsAlloc() 和 TlsFree() 做类似的事情。或者,如果我使用 Boost.Thread,Foo 将有一个 boost::thread_specific_ptr 类型的非静态成员。

然而,实际上,我正在尝试编写可移植的 C++11。 C++11 thread_local关键字不适用于非静态数据成员。因此,如果您希望每个线程有一个 Bar 很好,但如果您希望每个 Foo 每个线程有一个 Bar,那就不行了。

因此,据我所知,我需要定义一个从 Foos 到 Bars 的线程本地映射,然后处理如何在 Foo 被销毁时进行适当清理的问题。但在我开始之前,我在这里发帖是希望有人能阻止我说“有一种更简单的方法”。

(顺便说一句,我不使用 pthread_key_create() 或 boost::thread_specific_ptr 的原因是,如果我理解正确,他们假设所有线程都将分别使用 pthreads 或 Boost.Thread 产生。我不想让关于我的代码的用户将如何产生线程的任何假设。)

最佳答案

你要 Foo包含 thread_local类型变量 Bar .如前所述,因为 thread_local不能应用于数据成员,我们必须做一些更间接的事情。底层行为将针对 Bar 的 N 个实例。存在于 Foo 的每个实例中,其中 N 是存在的线程数。

这是一种效率低下的方法。有了更多的代码,它可以做得更快。基本上,每个 Foo 将包含一个 TLS 映射。

#include <unordered_map>

class Bar { ... };

class Foo {
private:
  static thread_local std::unordered_map<Foo*, Bar> tls;
public:    
  // All internal member functions must use this too.
  Bar *get_bar() {
    auto I = tls.find(this);
    if (I != tls.end())
      return &I->second;
    auto II = tls.emplace(this, Bar()); // Could use std::piecewise_construct here...
    return &II->second.second;
  }
};

关于multithreading - C++11 中的动态 TLS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22446534/

相关文章:

std::multimap 中的 c++ 枚举类

java - tomcat的ThreadLocalLeakPreventionListener到底是做什么的?

c - C中的_Thread_local存储类说明符?

spring - spring executor中java executor framework的invokeAll等价方法

c++ - 为什么并行读取数组会导致内存泄漏?

c# - 如何使 .NET COM 对象成为单元线程?

使用线程局部变量进行 Python 日志记录

python - 一些Python代码的解释

c++ - `Object obj(args...)` 和 `Object obj{args...}` 有什么区别?

c++ - 如何在我的 dll 接口(interface)或 ABI 中使用标准库 (STL) 类?