2010-12-15 169 views
0

fournit la manière très pratique pour traverser le récipient avec itération,Quand utiliser mutex avec itération. C++ C++

for(vector<int>::const_iterator p = c.begin(); p!=c.end();p++){} 

mais si quand cela est en train de subir, quelqu'un c.push_back(10).

Va-t-il rompre la boucle?

Devrais-je utiliser le mutex chaque fois que j'utilise le fonctionnement du conteneur?

Merci.

Répondre

2

Oui, il y a une condition de concurrence ici.

Si vous utilisez un conteneur STL à partir de plusieurs threads et qu'au moins l'un de ces threads peut modifier le conteneur, vous devez synchroniser l'accès au conteneur.

La façon la plus simple d'y parvenir est d'utiliser un mutex. Une autre option consisterait à trouver ou à implémenter un conteneur à thread sécurisé offrant les fonctionnalités dont vous avez besoin.

2

Oui, vous devriez le faire lorsque des écritures sont possibles à partir d'un autre thread.

http://www.sgi.com/tech/stl/thread_safety.html

Si plusieurs threads accéder à un seul récipient, et au moins un fil peut potentiellement écrire, l'utilisateur est chargé d'assurer l'exclusion mutuelle entre les fils pendant le conteneur accès.

1

Vous avez deux problèmes. Tout d'abord, vous avez un problème d'invalidation de l'itérateur. Parce que push_back augmente la taille du vecteur, il a la possibilité d'invoquer une allocation. chaque fois que la capacité (pas le nombre d'éléments) d'un vecteur change, tous les itérateurs dans le vecteur sont invalidés. Ceci est plus facile à traiter en vous assurant d'appeler reserve() avant de commencer la boucle pour vous assurer qu'il y a assez d'espace dans le vecteur pour satisfaire toutes les tentatives push_back futures pendant que la boucle s'exécute.

L'autre problème, comme mentionné dans les autres articles, est que vous avez une condition de concurrence lorsqu'une insertion peut s'exécuter simultanément à l'élément auquel vous accédez.

0

Oui, vous devez protéger le vecteur entier avec un mutex. Et c'est une bonne raison de ne pas utiliser de vecteurs pour partager des données entre les threads. La plupart du temps, nous utilisons des files d'attente, protégeant les push/pop avec des verrous. Si vous avez besoin de partager des données à l'aide de gros tampons, je vous recommande d'utiliser une sorte de structure personnalisée avec "pages", donc, vous ne pouvez bloquer qu'une petite partie, et laisser d'autres threads s'exécuter à différents endroits de la mémoire. le même temps.

0

Le plus simple est de verrouiller et déverrouiller avant itération après avoir terminé

  1. mutex verrouillage
  2. Iteration
  3. mutex déverrouiller