Linux 如何分配线程本地存储?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6021273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 04:06:37  来源:igfitidea点击:

How to allocate thread local storage?

c++linuxmultithreadingnew-operatorthread-local-storage

提问by WilliamKF

I have a variable in my function that is static, but I would like it to be static on a per thread basis.

我的函数中有一个静态变量,但我希望它在每个线程的基础上都是静态的。

How can I allocate the memory for my C++ class such that each thread has its own copy of the class instance?

如何为我的 C++ 类分配内存,以便每个线程都有自己的类实例副本?

AnotherClass::threadSpecificAction()
{
  // How to allocate this with thread local storage?
  static MyClass *instance = new MyClass();

  instance->doSomething();
}

This is on Linux. I'm not using C++0x and this is gcc v3.4.6.

这是在 Linux 上。我没有使用 C++0x,这是 gcc v3.4.6。

采纳答案by ravenspoint

#include <boost/thread/tss.hpp>
static boost::thread_specific_ptr< MyClass> instance;
if( ! instance.get() ) {
    // first time called by this thread
    // construct test element to be used in all subsequent calls from this thread
    instance.reset( new MyClass);
}
    instance->doSomething();

回答by Nawaz

If you're working with MSVC++, you can read Thread Local Storage (TLS)

如果您正在使用 MSVC++,您可以阅读线程本地存储 (TLS)

And then you can see this example.

然后你可以看到这个例子

Also, be aware of the Rules and Limitations for TLS

此外,请注意TLS规则和限制

回答by Tony The Lion

On Windows you can use TlsAllocand TlsFreeto allocate storage in the threads local storage.

在 Windows 上,您可以使用TlsAllocTlsFree在线程本地存储中分配存储。

To set and retrieve values in with TLS, you can use TlsSetValueand TlsGetValue, respectively

要使用 TLS 设置和检索值,您可以分别使用TlsSetValueTlsGetValue

Hereyou can see an example on how it would be used.

在这里,您可以看到有关如何使用它的示例。

回答by Jason

If you're using Pthreads you can do the following:

如果您使用的是 Pthreads,您可以执行以下操作:

//declare static data members
pthread_key_t AnotherClass::key_value;
pthread_once_t AnotherClass::key_init_once = PTHREAD_ONCE_INIT;

//declare static function
void AnotherClass::init_key()
{
    //while you can pass a NULL as the second argument, you 
    //should pass some valid destrutor function that can properly
    //delete a pointer for your MyClass
    pthread_key_create(&key_value, NULL);
}

void AnotherClass::threadSpecificAction()
{
  //Initialize the key value
  pthread_once(&key_init_once, init_key);

  //this is where the thread-specific pointer is obtained
  //if storage has already been allocated, it won't return NULL

  MyClass *instance = NULL;
  if ((instance = (MyClass*)pthread_getspecific(key_value)) == NULL)
  {
    instance = new MyClass;
    pthread_setspecific(key_value, (void*)instance);
  }

  instance->doSomething();
}

回答by tvn

boost::thread_specific_ptris the best way as it portable solution.

boost::thread_specific_ptr是最好的方法,因为它是便携式解决方案。

On Linux & GCC you may use __threadmodifier.

在 Linux 和 GCC 上,您可以使用__thread修饰符.

So your instance variable will look like:

所以你的实例变量看起来像:

static __thread MyClass *instance = new MyClass();

回答by Deqing

It is worth noting that C++11 introduces the thread_localkeyword.

值得注意的是,C++11 引入了thread_local关键字。

Here is an example from Storage duration specifiers:

以下是存储持续时间说明符的示例:

#include <iostream>
#include <string>
#include <thread>
#include <mutex>

thread_local unsigned int rage = 1; 
std::mutex cout_mutex;

void increase_rage(const std::string& thread_name)
{
    ++rage;
    std::lock_guard<std::mutex> lock(cout_mutex);
    std::cout << "Rage counter for " << thread_name << ": " << rage << '\n';
}

int main()
{
    std::thread a(increase_rage, "a"), b(increase_rage, "b");
    increase_rage("main");

    a.join();
    b.join();

    return 0;
}

Possible output:

可能的输出:

Rage counter for a: 2
Rage counter for main: 2
Rage counter for b: 2

回答by Arek Bal

Just a side note... MSVC++ supports declspec(thread) from VSC++2005

只是一个旁注... MSVC++ 支持来自 VSC++2005 的 declspec(thread)

#if (_MSC_VER >= 1400)
  #ifndef thread_local     
    #define thread_local __declspec(thread)
  #endif
#endif

Main problem is(which is solved in boost::thread_specific_ptr) variables marked with it can't contain ctor or dtor.

主要问题是(在 boost::thread_specific_ptr 中解决)用它标记的变量不能包含 ctor 或 dtor。

回答by Arne

C++11 specifies a thread_localstorage type, just use it.

C++11 指定了一种thread_local存储类型,直接使用即可。

AnotherClass::threadSpecificAction()
{
  thread_local MyClass *instance = new MyClass();
  instance->doSomething();
}

One optional optimization is to also allocate on thread local storage.

一种可选的优化是也分配线程本地存储。

回答by chema989

Folly (Facebook Open-source Library)has a portable implementation of Thread Local Storage.

Folly(Facebook 开源库)有一个可移植的线程本地存储实现。

According its authors:

根据其作者:

Improved thread local storage for non-trivial types (similar speed as pthread_getspecificbut only consumes a single pthread_key_t, and 4x faster than boost::thread_specific_ptr).

改进了非平凡类型的线程本地存储(速度与 相似, pthread_getspecific但仅消耗单个pthread_key_t,比 快 4 倍boost::thread_specific_ptr)。

If your looking for a portable implementation of Local Storage Thread, this library is a good option.

如果您正在寻找本地存储线程的可移植实现,这个库是一个不错的选择。