Des threads classe Vector en C++
Que quelqu'un connait un moyen rapide et sale de thread-safe classe vector en c++? Je suis le multithreading un peu de code, et je crois que le problème que j'ai est liée à la façon dont les vecteurs sont utilisés. J'ai l'intention de réécrire le code, mais avant je me fou de refaire le code, je tiens à le tester avec un des threads vecteur pour en être sûr. J'ai aussi la figure si une telle chose existe, il serait beaucoup plus facile que d'écrire ma propre version.
OriginalL'auteur ras2124 | 2009-07-08
Vous devez vous connecter pour publier un commentaire.
Cela est difficile parce que des algorithmes.
Supposons que vous avez enveloppé vecteur de sorte que l'ensemble de ses fonctions de membre sont sérialisés à l'aide d'un mutex, comme Java synchronisé méthodes. Puis des appels simultanés à
std::remove
sur ce vecteur n'est pas sûr, parce qu'ils s'appuient sur la recherche au niveau du vecteur et de changer en fonction de ce qu'ils voient.De sorte que votre LockingVector aurait besoin de spécialiser chaque modèle dans les algorithmes standards, pour verrouiller autour de l'ensemble de la chose. Mais alors d'autres algorithmes comme
std::remove_if
serait l'appel de code défini par l'utilisateur en vertu de la serrure. Ce faisant silencieusement derrière les scènes, c'est une recette pour le verrouillage de l'inversion dès que quelqu'un commence à créer des vecteurs d'objets, qui eux-mêmes en interne tirer les verrous autour de l'ensemble de leurs méthodes.En réponse à votre question: non, non, je ne connais pas. Pour un test rapide de la sorte dont vous avez besoin, je vous recommande de commencer avec:
Puis déposez-la dans comme un remplacement de conteneurs, et de commencer à mettre en œuvre des fonctions de membre (et membre du typedefs, et les opérateurs) jusqu'à ce qu'il compile. Vous remarquerez assez rapidement si l'un de vos code est d'utiliser des itérateurs sur le vecteur d'une manière qui ne peut tout simplement pas être thread-safe de l'intérieur, et, si besoin, vous pouvez modifier temporairement le code d'appel dans les cas de verrouiller le vecteur via les méthodes publiques.
OriginalL'auteur Steve Jessop
Vous pouvez consulter TBB (comme concurrent_vector). Je n'ai jamais utilisé mais, honnêtement, je trouve que mettre le champ d'application de la garde des objets autour de l'accès plus facile (surtout si le vecteur est bien encapsulé).
OriginalL'auteur Todd Gardner
Je pense que vous le trouverez beaucoup plus facile de continuer à utiliser std::vector, mais pour protéger l'accès simultané à l'aide de une sorte de mutex ou d'un autre système d'exploitation objet de synchronisation. Vous aurez certainement souhaitez utiliser RAII si vous utilisez un mutex.
Je n'ai pas envie de vous. Si vous ne savez pas encore où plusieurs threads accèdent à la même vecteur, vous pourriez aussi bien commencer avec un design qui a du multi-threading dans l'esprit depuis le début. Bonne chance.
OriginalL'auteur Brian Neal
Que Scott Meyers explique le effective STL livre, par un fil conteneur sûr vous pouvez vous attendre:
C'est tout. Vous ne pouvez pas s'attendre à beaucoup d'autres choses telles que la sclérose écrit sur le même conteneur être thread-safe. Si c'est tout ce que vous voulez, alors vous pouvez prendre un coup d'oeil à STLPort. Si non, alors la seule option que je vois est de contenir le vecteur dans une classe qui synchronise l'accès au vecteur.
STLPort est une implémentation STL qui propose (à partir de la page d'accueil) "# Exception de la sécurité et de la sécurité des threads." TOUS STL implémentations sont censés offrir exception de la sécurité par la conception, mais il n'est pas nécessaire d'offrir à la sécurité des threads. STLPort.
Vous pouvez voir ce que STLPort entend par "filet de sécurité" ici. Fondamentalement, ils signifient les choses qui C++ et/ou le matériel vous donner gratuitement — qui est-à-dire, Scott Meyers conditions. La seule façon pour une bibliothèque réalisateur à vis de ce genre de "filet de sécurité" est par délibérée de sabotage; par exemple, il pourrait ajouter une variable globale
x
(non protégé par un cadenas) et le toucher sur chaque écriture, ou il pourrait ajouter unmutable
membre est touché par des lectures, ou quelque chose comme ça.OriginalL'auteur Naveen
J'oublie qui a parlé de cela, mais une stratégie pour la réalisation d'un thread-safe conteneur est comme suit:
f = myvec[i]
, utilisezif (myvec.tryGet(i, &f)) {...}
et de mettre en œuvre la classe en conséquence.Remarque: attention à l'itération. Vous devez être intelligent sur le maintien d'une jamais-rétrécissement de vecteur avec des bornes de vérification des itérateurs ou vous pourriez avoir du code qui a dépassement de capacité des erreurs de type.
Le boiteux et le moyen facile de fournir un "thread-safe" vecteur est de prendre un vecteur standard et verrouiller le vecteur pour chaque méthode. Mais si vous faites cela, vous pourrait encore se retrouver avec de code cassé (par exemple, une boucle qui itère de 0 à vec.le comte avez compter de changement alors que c'est une itération).
Un 2ème moyens de fournir un "thread-safe" conteneurs est de créer immuable conteneurs (chaque méthode renvoie un nouveau conteneur. Ce n'était certainement discuté par Eric Lippert. C'est le C#, mais facilement se traduit par un code C++, la plupart du temps. Vous aurez toujours besoin de verrouiller le conteneur lorsque vous l'utilisez, mais tous les effrayant questions impliquant des dépassements de la mémoire tampon lorsque les itérateurs pause et autres joyeusetés en aller. Mise en œuvre d'une immuable conteneur est probablement relativement 2ème de la nature à ceux qui ont de l'expérience avec la programmation fonctionnelle.
OriginalL'auteur Brian
Si vous ne l'avez pas déjà fait, pensez à utiliser concurrent_vector de la tbb de la bibliothèque. C++ STL vecteurs ne sont pas thread-safe donc, si vous envisagez sur la modification de vecteur de ressources à partir de plusieurs threads, la solution la plus simple que j'ai trouvé est d'utiliser concurrent_vector.
OriginalL'auteur Yohannis