Programing

스레드 로컬 스토리지를 할당하는 방법은 무엇입니까?

lottogame 2020. 12. 14. 07:45
반응형

스레드 로컬 스토리지를 할당하는 방법은 무엇입니까?


내 함수에 정적 변수가 있지만 스레드별로 정적 변수를 원합니다.

각 스레드가 클래스 인스턴스의 자체 복사본을 갖도록 내 C ++ 클래스에 대한 메모리를 어떻게 할당 할 수 있습니까?

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

  instance->doSomething();
}

이것은 Linux에 있습니다. 저는 C ++ 0x를 사용하지 않으며 이것은 gcc v3.4.6입니다.


#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();

C ++ 11에 thread_local키워드가 도입된다는 점은 주목할 가치가 있습니다.

다음은 저장 기간 지정자 의 예입니다 .

#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;
}

가능한 출력 :

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

boost::thread_specific_ptr 휴대용 솔루션으로서 가장 좋은 방법입니다.

Linux 및 GCC에서는 __threadmodifier를 사용할 수 있습니다 .

따라서 인스턴스 변수는 다음과 같습니다.

static __thread MyClass *instance = new MyClass();

Pthread를 사용하는 경우 다음을 수행 할 수 있습니다.

//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();
}

C ++ 11은 thread_local스토리지 유형을 지정 합니다. 사용하기 만하면됩니다.

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

하나의 선택적 최적화는 스레드 로컬 스토리지에도 할당하는 것입니다.


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

And then you can see this example.

Also, be aware of the Rules and Limitations for TLS


On Windows you can use TlsAlloc and TlsFree to allocate storage in the threads local storage.

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

Here you can see an example on how it would be used.


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

#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.


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

According its authors:

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

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

참고URL : https://stackoverflow.com/questions/6021273/how-to-allocate-thread-local-storage

반응형