57 Stimmen

Wie weist man dem Thread lokalen Speicher zu?

Ich habe eine Variable in meiner Funktion, die statisch ist, aber ich möchte, dass es statisch auf einer pro Thread-Basis sein.

Wie kann ich den Speicher für meine C++-Klasse so zuweisen, dass jeder Thread seine eigene Kopie der Klasseninstanz hat?

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

  instance->doSomething();
}

Dies geschieht unter Linux. Ich bin nicht mit C++0x und dies ist gcc v3.4.6.

70voto

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

69voto

Deqing Punkte 12880

Es ist erwähnenswert, dass C++11 die thread_local Stichwort.

Hier ist ein Beispiel aus Angaben zur Speicherdauer :

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

Mögliche Ausgabe:

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

14voto

tvn Punkte 624

boost::thread_specific_ptr ist die beste Lösung, da sie tragbar ist.

Unter Linux & GCC können Sie folgendes verwenden __thread Modifikator .

Ihre Instanzvariable wird also wie folgt aussehen:

static __thread MyClass *instance = new MyClass();

11voto

Jason Punkte 30904

Wenn Sie Pthreads verwenden, können Sie wie folgt vorgehen:

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

4voto

Nawaz Punkte 339767

Wenn Sie mit MSVC++ arbeiten, können Sie Folgendes lesen Thread Local Storage (TLS)

Und dann können Sie dies sehen Beispiel .

Achten Sie auch auf die Regeln und Beschränkungen für TLS

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X