J'ai plusieurs threads modifiant un vecteur stl et une liste de stl.
Je veux éviter de devoir prendre un verrou si le conteneur est vide
le code suivant serait-il threadsafe? Et si les articles étaient une liste ou une carte? P>
5 Réponses :
stl n'est pas le fil sûr et vide aussi. Si vous souhaitez faire du coffre-fort, vous devez fermer toutes ses méthodes par mutex ou autre synchronisation p>
Il n'y a pas de garantie de fil-sécurité sur quoi que ce soit dans les conteneurs et les algorithmes de la STL. P>
Alors, non. p>
Indépendamment de la sécurité vide ou non du fil de sécurité, votre code ne sera pas, comme écrit, accomplir votre objectif.
class A { vector<int> items void DoStuff() { if(!items.empty()) { //Another thread deletes items here. AquireLock(); DoStuffWithItems(); ReleaseLock(); } } }
Votre point (// Un autre thread supprime les éléments ici.) Est clair. Pourtant, il est également évident que vous pouvez vérifier vide () après avoir acquis la serrure pour être sûr.
@skwllSP: un point valide. Si vide () code> est le fil de sécurité, vérifiez d'abord à vide, le verrouillage, puis la revérisation peut éviter un verrou inutile.
Cela dépend de ce que vous attendez. Les autres réponses sont correctes que en général em>, les conteneurs standard C ++ ne sont pas thread-coffre-fort et que en particulier em> votre code ne protège pas contre un autre fil modifiant le conteneur entre votre appel à Donc, pour préserver les malentendus: Votre code ne garantit pas Mais votre code peut toujours être utile, car tout ce que vous voulez faire est d'éviter les créations de verrouillage redondantes. Votre code ne donne pas de garanties mais il peut em> empêcher une création de verrouillage inutile. Cela ne fonctionnera pas dans tous les cas (les autres threads peuvent toujours vider le conteneur entre votre chèque et votre verrou) mais dans certains cas em>. Et si tout ce que vous avez après est une optimisation en omettant une serrure redondante, votre code accomplit cet objectif. P>
Assurez-vous simplement que tout accès em> au conteneur est em> protégé par des serrures. P>
Au fait, ce qui précède est Strictement parler em> comportement indéfini strong>: une implémentation stl est théoriquement autorisée à modifier En pratique, cependant, je suis sûr que vide code> et l'acquisition du verrou (mais cette question n'est pas liée à la sécurité du thread de
vecteur :: vide p>). P>
éléments code> ne sera pas vide à l'intérieur du bloc. strong> p>
Mubble code> Membres à l'intérieur de l'appel
vide code>. Cela signifierait que l'appelait apparemment inoffensif (parce que la lecture seule) à
vide code> peut em> causer réellement un conflit. Malheureusement, vous ne peut pas em> s'appuyer sur l'hypothèse que les appels en lecture seule sont en sécurité avec des conteneurs STL. P>
vecteur :: vide code> pas em> modifie les membres em>. Mais déjà pour
Liste :: vide code> Je suis moins sûr. Si vous voulez vraiment les garanties em>, alors verrouillez-la tous les em> l'accès ou n'utilisez pas les conteneurs STL. P>
Comme il est déjà répondu, le code ci-dessus n'est pas le fil sûr et le verrouillage est obligatoire avant de faire quoi que ce soit avec le conteneur. Mais ce qui suit devrait avoir une meilleure performance que de toujours verrouiller et je ne peux penser à une raison pour laquelle il peut être dangereux. L'idée ici est que le verrouillage peut être coûteux et nous l'évigeons, chaque fois que cela n'était pas vraiment nécessaire.
class A { vector<int> items; void DoStuff() { if(!items.empty()) { AquireLock(); if(!items.empty()) { DoStuffWithItems(); } ReleaseLock(); } } }
Merci pour les réponses. Pour clarifier la question: un autre thread va ajouter aux éléments. Aucun autre thread ne retirera des éléments - supplies ne se produira qu'à l'intérieur de Dostuffwithitems () et seulement un seul appels de threads Dostuff (). C'est bon si les articles.empty () renvoie false alors qu'un autre fil y ajoutent. Ce n'est pas correct si les articles.empty () provoque une crash de l'application si un autre thread y ajoutant