Je suis relativement nouveau dans la bibliothèque standard C++ et j'utilise des listes de bibliothèques standard pour une implémentation multithread spécifique. J'ai remarqué qu'il pourrait y avoir un truc avec l'utilisation de listes que je n'ai pas vu sur un tutoriel/blog/forum et bien que cela semble évident pour moi ne semble pas être considéré par quiconque. Alors peut-être que je suis trop nouveau et peut-être manquer quelque chose alors j'espère que quelqu'un de plus intelligent que moi peut peut-être valider ce que j'essaie d'accomplir ou m'expliquer ce que je fais de mal. Par conséquent, nous savons qu'en général, les conteneurs de bibliothèque standard ne sont pas thread-safe - mais cela semble plus qu'une règle. Avec les listes, il semble qu'il existe un niveau de tolérance pour la sécurité des threads. Laissez-moi vous expliquer, nous savons que les listes ne sont pas invalidées si nous ajoutons/supprimons de la liste. Le seul itérateur qui obtient invalidée est l'élément supprimé - que vous pouvez fixer avec la ligne de code suivante:Listes et environnements multithread
it = myList.erase(it)
Alors Maintenant, supposons que nous avons deux fils et les appeler fil 1 et 2. fil
La responsabilité de Thread 1 est d'ajouter à la liste. Il le traite comme une file d'attente, il utilise donc l'appel de fonction std :: list :: push_back().
La responsabilité de Thread 2 est de traiter les données stockées dans la liste comme une file d'attente et ensuite, après le traitement, de supprimer des éléments de la liste.
Il est garanti que Thread 2 ne supprimera pas les éléments de la liste qui viennent d'être ajoutés lors de son traitement et Thread 1 garantit qu'il mettra en attente les données nécessaires bien avant le traitement de Thread 2. Cependant, gardez à l'esprit que des éléments peuvent être ajoutés pendant le traitement de Thread 2.
Il semble donc que ce soit une utilisation raisonnable des listes dans cet environnement multithread sans l'utilisation de verrous pour la protection des données. La raison pour laquelle je dis son raisonnable est parce que, pour l'essentiel, la discussion 2 sera uniquement les données jusqu'à présent de telle sorte qu'il peut retreive l'itérateur fin du courant indiqué par le pseudo-code suivant:
Thread 2 {
iter = myList.begin();
lock();
iterEnd = myList.end(); // lock data temporarily in order to get the current
// last element in the list
unlock();
// perform necessary processing
while (iter != iterEnd) {
// process data
// ...
// remove element
iter = myList.erase(iter);
}
}
Discussion 2 utilise un verrou pour un très peu de temps juste pour savoir où arrêter le traitement, mais la plupart du temps Thread 1 et Thread 2 ne nécessitent aucun autre verrouillage. En outre, Thread 2 peut éventuellement éviter le verrouillage si son étendue pour connaître le dernier élément en cours est flexible.
Quelqu'un voit quelque chose de mal avec ma suggestion?
Merci!
De plus, les opérations d'insertion/suppression de liste à double liaison ne sont pas atomiques et peuvent corrompre le nœud étant simultané. Cela se produira si la longueur de la liste est proche de 1. – Basilevs