C++ Vecteur, push_back partir d'un autre thread s'écraser?
J'ai inattendu affirmations faillures dans mon code à l'aide d'un vérifiée implémentation de la STL.
Après quelques recherches, j'ai réduit le problème à un push_back dans un vecteur appelé à partir d'un autre thread que celui dans lequel le vecteur a été créé.
Le code le plus simple pour reproduire ce problème est :
class SomeClass
{
private:
std::vector<int> theVector;
public:
SomeClass ()
{
theVector.push_back(1); //Ok
}
void add()
{
theVector.push_back(1); //Crash
}
};
La seule différence est que SomeClass est instanciée à partir de mon thread principal, et ajouter est appelée à partir d'un autre thread. Cependant, il n'est pas concurency question : dans la forme la plus simple de code que j'ai utilisé pour le dépannage, personne n'est en lecture ou en écriture à partir de ce vecteur, sauf les cas que j'ai mentionnés ci-dessus.
Le suivi dans le push_back code, j'ai remarqué que certaines méthodes de std::vector comme count() ou size() retour à ordures, lorsqu'elle est appelée à partir de l'autre thred (méthode "ajouter"), et les valeurs correctes lorsqu'il est appelé à partir de la création de thread (dans le constructeur par exemple)
Dois-je en conclure que std::vector n'est pas utilisable dans un multithread de l'environnement ? Ou est-il une solution pour ce problème ?
EDIT : supprimé volatils
EDIT 2 : pensez-vous qu'il est possible que le problème ne réside pas dans multithread ? Dans mon essai, ajouter est appelée qu'une seule fois (vérifié à l'aide d'un point de rupture). Si je supprime le push_back à partir du constructeur, je plante toujours. Donc au final, même avec un seul appel à un vecteur de la méthode, dans une fonction appelée une fois que l'assertion échoue. Par conséquent, il ne peut pas être concurency, ou ... ?
Êtes-vous dans un environnement où chaque thread a son propre tas?
Essayez d'appeler
reserve
.-1: Votre code ne peut même pas compiler depuis
push_back()
n'est pas déclaré comme "volatile". Pouvez-vous fournir une vue plus détaillée de code/description?"Dois-je en conclure que std::vector n'est pas utilisable dans un multithread de l'environnement ?" - pas du tout, le vecteur n'est pas censé faire toute différente dans les multi-threaded application dans un seul thread. En fait, si vous comparez le C++0x (qui est thread-conscient) vecteur n'est pas différent de C++97 (ce qui n'est pas thread-conscient). Il est de la responsabilité de l'application, et non le vecteur, de fournir la sérialisation, si nécessaire. Dans votre cas, je pense que votre affirmation que le multi-threading n'a pas de rôle dans les comportements observables est susceptible d'être faux, faire le bon verrouillage au lieu de spéculer.
OriginalL'auteur Dinaiz | 2010-12-10
Vous devez vous connecter pour publier un commentaire.
Si vous pouvez garantir que personne ne soit en écriture ou en lecture à partir du vecteur lorsque vous appelez push_back, il n'y a pas de raison qu'il doit échouer. Vous pourriez avoir affaire à de plus haut niveau de corruption de la mémoire. Vous devez vérifier que "cette" pointe vers une véritable instance de SomeClass, vérifier les autres membres, etc.
SomeClass
instance.Vous les gars sont en effet droite : le problème n'était pas la vactor ou le fils, mais le SomeClass instance. Merci beaucoup pour vos idées
OriginalL'auteur Puppy
std::vector
certainement est utilisable dans un environnement multi-thread, à condition de ne pas accéder au vecteur à partir de ses deux fils à la fois. Je le fais tout le temps sans problème.Depuis
vector
n'est pas le problème, vous devez regarder de plus près vos mécanisme de synchronisation, comme c'est probablement le problème.J'ai remarqué que vous avez marqué le
vector
commevolatile
. Pensez-vous que c'volatile
permet la synchronisation? Car il ne sera pas. Voir ici pour plus d'informations.EDIT: fourni à l'Origine du mauvais lien. C'est maintenant corrigé. Désolé pour la confusion.
OriginalL'auteur John Dibling
La plupart des TSL, les implémentations ne sont pas thread-safe. Vous aurez besoin d'utiliser la synchronisation des threads (par exemple mutex) pour empêcher les deux fils de piétiner les uns sur les autres lors de l'accès au vecteur. Fondamentalement, ce que vous devez faire est de créer une classe qui contient le vecteur et un mutex et les fonctions d'accesseur qui protègent le vecteur de la lecture et de l'écriture des opérations.
Cette réponse contient la même erreur que @pts’. Mutex et de synchronisation sont complètement hors de propos ici.
Le gène de la définition est aussi bon que tout. “thread-safe” est une valeur en qualification depuis le pas de deux personnes d'accord sur sa signification.
Je suis d'accord "thread-safe" est une phrase inutile. Simplement en apportant à l'autre, éventuellement, de la perception commune.
Dibling -- "peuple" peut "signifie" beaucoup de choses, nous ne sommes pas ici de discuter de la psychologie. YUou ne pouvez pas utiliser les concepts stables de toute façon que vous voulez, surtout lorsque cette utilisation n'a pas de sens.
OriginalL'auteur Zac Howland
Si la Bibliothèque Standard supporte le multithreading est définie par l'implémentation. Vous devez lire la documentation de votre compilateur.
De plus ce que vous pouvez faire est d'ajouter les messages de log comme dans le code suivant:
Assurez-vous que l'instance de la
SomeClass
est existe toujours lorsque vous appelezadd
fonction.OriginalL'auteur Kirill V. Lyadvinsky