it-swarm.com.de

Wie reserviere ich Thread-lokalen Speicher?

Ich habe eine Variable in meiner Funktion, die statisch ist, aber ich möchte, dass sie pro Thread statisch ist.

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

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

  instance->doSomething();
}

Dies ist unter Linux. Ich verwende kein C++ 0x und das ist gcc v3.4.6.

56
WilliamKF
#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();
67
ravenspoint

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

Hier ist ein Beispiel von Angabe der 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
64
Deqing

boost::thread_specific_ptr ist der beste Weg als portable Lösung.

Unter Linux und GCC können Sie __thread Modifikator .

Ihre Instanzvariable sieht also so aus:

static __thread MyClass *instance = new MyClass();
14
tvn

Wenn Sie Pthreads verwenden, können Sie Folgendes tun:

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

C++ 11 gibt ein thread_local Speichertyp, benutze ihn einfach.

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

Eine optionale Optimierung besteht darin, auch lokalen Thread-Speicher zuzuweisen.

4
Arne

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

Und dann können Sie dies sehen Beispiel .

Beachten Sie auch die Regeln und Einschränkungen für TLS

3
Nawaz

Unter Windows können Sie TlsAlloc und TlsFree verwenden, um Speicher im lokalen Speicher des Threads zuzuweisen.

Um Werte mit TLS festzulegen und abzurufen, können Sie TlsSetValue bzw. TlsGetValue verwenden

Hier sehen Sie ein Beispiel, wie es verwendet werden würde.

3
Tony The Lion

Nur eine Randnotiz ... MSVC++ unterstützt declspec (thread) von VSC++ 2005

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

Das Hauptproblem sind (was in boost :: thread_specific_ptr behoben wird) Variablen, die mit diesem Attribut gekennzeichnet sind und weder ctor noch dtor enthalten können.

2
Arek Bal

Folly (Facebook Open-Source-Bibliothek) hat eine portable Implementierung von Thread Local Storage.

Nach den Autoren:

Verbesserter lokaler Thread-Speicher für nicht-triviale Typen (ähnliche Geschwindigkeit wie pthread_getspecific verbraucht aber nur einen einzigen pthread_key_t und 4x schneller als boost::thread_specific_ptr).

Wenn Sie eine portable Implementierung von Local Storage Thread suchen, ist diese Bibliothek eine gute Option.

1
chema989