C++11: Nichttriviale Thread-Lokale Statische Variable?

Habe ich eine Klasse X:

class X { ... }

Ich dies tun möchten:

void f()
{
    thread_local static X x = ...;

    ...
}

(eigentlich bin ich mit gcc, so dass Schlüsselwort "__thread")

aber ich kann nicht, weil Sie nur triviale thread_locals.

Was ist der beste work-around dafür?

Wenn ich es so machen:

void f()
{
    thread_local static X* p = 0;

    if (!p)
       p = new X(...);

    X& x = *p;

    ...
}

dann:

  1. der Destruktor wird nicht aufgerufen, wenn der thread beendet
  2. unnötige dynamische Speicherzuweisung.

Update:

Hier ist was ich habe, so weit:

#include <iostream>
#include <type_traits>

using namespace std;

class X { public: X() { cout << "X::X()" << endl; }; ~X() { cout << "X::~X()" << endl; } };

void f()
{
        static __thread bool x_allocated = false;
        static __thread aligned_storage<sizeof(X),
             alignment_of<X>::value>::type x_storage;

        if (!x_allocated)
        {
                new (&x_storage) X;
                x_allocated = true;
                //add thread cleanup that calls destructor
        }

        X& x = *((X*) &x_storage);
}

int main()
{
        f();
}

Dieser behebt das dynamic memory allocation problem. Ich brauche nur hinzuzufügen, der thread cleanup-handler. Gibt es dafür einen Mechanismus mit pthreads?

  • Warum können Sie nur triviale thread-einheimischen? Par-standard?
  • Ich dachte so? GCC scheint nicht, es zu mögen.
  • Ich glaube nicht, dass der standard solche Beschränkungen, und GCC nicht implementiert C++11 thread local storage.
  • gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Thread_002dLocal.html
  • Das ist eine gcc-Erweiterung, nicht C++11 thread_local. Siehe hier. Also, wenn es nicht umgesetzt wird, werden Sie nicht haben, das problem der Trivialität.
  • Ja, ich sehe jetzt. Was ist der beste workaround in der Zwischenzeit?
  • sorry, wenn ich wusste, ich hätte eine Antwort 🙂
  • stackoverflow.com/questions/12049684/...
  • Ich glaube, ich habe einen Fall, wo thread_local nicht-POD-Objekt ist nicht initialisiert, in VS 2015 bei der Verwendung des nativen Bibliothek aus .NET. Manchmal.

Schreibe einen Kommentar