C++11: Non Trivial Thread Local Variable Statique?
J'ai une classe X:
class X { ... }
Je veux faire ceci:
void f()
{
thread_local static X x = ...;
...
}
(en fait, je suis en utilisant gcc si le mot clé est "__thread")
mais je ne peux pas parce que vous ne pouvez avoir trivial thread_locals.
Quelle est la meilleure façon de contourner ce pour cela?
Si je le fais de cette façon:
void f()
{
thread_local static X* p = 0;
if (!p)
p = new X(...);
X& x = *p;
...
}
alors:
- le destructeur ne sera pas appelé lorsque le thread sorties
- inutile allocation dynamique de la mémoire.
Mise à jour:
Voici ce que j'ai à ce jour:
#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();
}
Cela corrige l'allocation dynamique de la mémoire de problème. J'ai juste besoin d'ajouter le thread de nettoyage de gestionnaire. Est-il un mécanisme pour ce faire avec les pthreads?
Pourquoi vous ne pouvez avoir qu'trivial thread-habitants? Par de la norme?
J'ai pensé alors? GCC ne semble pas comme elle.
Je ne pense pas que le standard a de telles restrictions, et GCC ne pas mettre en œuvre de C++11 thread local storage encore.
gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Thread_002dLocal.html
C'est un gcc extension, pas du C++11
J'ai pensé alors? GCC ne semble pas comme elle.
Je ne pense pas que le standard a de telles restrictions, et GCC ne pas mettre en œuvre de C++11 thread local storage encore.
gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Thread_002dLocal.html
C'est un gcc extension, pas du C++11
thread_local
. Voir ici. Donc, chaque fois qu'il est mis en place, vous n'aurez pas le problème de la trivialité.OriginalL'auteur Andrew Tomazos | 2012-08-21
Vous devez vous connecter pour publier un commentaire.
La Norme décrit les
thread_local
comme un spécificateur de stockage comme les autres (static
,extern
etc.) dans le §7.1.1. Il n'y a pas de restriction à une "simple" types de données dans tous les sens du mot.Le problème est brièvement discuté dans un avant C++11 document de discussion N2147 (voir la section "Thread Variable Dynamique d'Initialisation"). Qui comprend une description des principaux problèmes rencontrés dans la mise en œuvre correcte. Apparemment, la GCC de mise en œuvre (
static __thread
) n'a pas résolu ces problèmes encore (ce qui est cohérent avec le fait que GCC ne supporte pas officiellement le C++11thread_local
).Une alternative est
boost::thread_specfic_ptr<>
mentionné dans ce précédent post et décrit ici.Une autre alternative est d'utiliser un
std::thread
objet de mettre en œuvre le fil et de s'assurer que chaque instance possède son propre copie de la variable, éventuellement, enveloppé dans ununique_ptr
.Je vais poster une nouvelle question, c'est plus facile.
stackoverflow.com/questions/12049684/...
OriginalL'auteur jogojapan
thread_local
et__thread
sont, en fait, pas la même chose. La principale différence entre eux est précisément celui que vous avez trébuché sur -thread_local
permet la variable non-POD. Malheureusement, cela a aussi des implications sur les performances. Voir cette question pour plus de détails au sujet de ces implications sur les performances.OriginalL'auteur Shachar Shemesh