36 votes

Comment puis-je écrire une structure sans verrouillage?

Dans mon application multithread et je vois une forte contention de verrouillage, empêchant une bonne évolutivité sur plusieurs cœurs. J'ai décidé d'utiliser une programmation sans verrouillage pour résoudre ce problème.

Comment puis-je écrire une structure sans verrouillage?

45voto

Suma Points 11966

Réponse courte est:

Vous ne pouvez pas.

Réponse longue est:

Si vous vous posez cette question, vous ne savez probablement assez pour être en mesure de créer un verrou libre de la structure. La création de verrouillage de structures libres est extrêmement difficile, et seuls les experts dans ce domaine peut le faire. Au lieu d'écrire votre propre, recherche pour l'un de mise en œuvre existantes. Lorsque vous le trouvez, vérifier comment il est utilisé, comment est-il documenté, s'il est bien prouvé, ce sont les limites - même certains de verrouillage structure sans autres personnes publiées sont cassés.

Si vous ne trouvez pas un verrou libre de la structure correspondant à la structure que vous utilisez actuellement, au lieu d'adapter l'algorithme de sorte que vous pouvez utiliser un existant.

Si vous insistez toujours sur la création de votre propre cadenas gratuit structure, assurez-vous de:

  • commencer avec quelque chose de très simple
  • comprendre le modèle de mémoire de votre plate-forme cible (y compris en lecture/écriture réorganisation des contraintes, les opérations atomiques)
  • étude beaucoup sur les problèmes d'autres personnes rencontrées lors de la mise en œuvre de verrouillage de structures libres
  • ne pas deviner si cela ne fonctionne pas, la preuve
  • fortement de tester le résultat

Plus de lecture:

Lock gratuit et d'attendre les algorithmes sans sur Wikipedia

Herb Sutter: sans Verrouillage de Code: Un Faux Sentiment de Sécurité

16voto

Niall Points 2074

Utilisez une bibliothèque telle que les Threading Building Blocks d'Intel , elle contient pas mal de structures et d'algorithmes sans verrouillage. Je ne recommanderais vraiment pas d'essayer d'écrire du code sans verrouillage vous-même, c'est extrêmement sujet aux erreurs et difficile à corriger.

12voto

Mecki Points 35351

Comme sblundy souligné, si tous les objets sont immuables, en lecture seule, vous n'avez pas besoin de vous soucier de verrouillage, cependant, cela signifie que vous pouvez copier des objets d'un lot. La copie implique généralement malloc et le malloc utilise le verrouillage de synchroniser les allocations de mémoire à travers les threads, donc des objets immuables peut acheter à moins que vous ne le pensez (malloc lui-même des échelles plutôt mal et le malloc est lente; si vous faites beaucoup de malloc dans une exécution de la section critique, ne pas s'attendre à de bonnes performances).

Quand vous avez seulement besoin de mettre à jour des variables simples (par exemple, 32 ou 64 bits int ou pointeurs), effectuez simplement une addition ou une soustraction d'opérations ou tout simplement permuter les valeurs de deux variables, la plupart des plates-formes offrent des "opérations atomiques" pour que (poursuite de la GCC offre de ces derniers). Atomique n'est pas la même que la thread-safe. Cependant, atomique permet de s'assurer, que si un thread écrit une version 64 bits de la valeur à un emplacement de mémoire, par exemple, et un autre thread lit, la lecture, on obtient la valeur avant l'opération d'écriture ou après l'opération d'écriture, mais jamais cassé de valeur entre l'opération d'écriture (par exemple, celui où les 32 premiers bits sont déjà les nouvelles, les 32 derniers bits sont toujours l'ancienne valeur! Cela peut se produire si vous n'utilisez pas accès atomique sur une telle variable).

Toutefois, si vous avez une structure C, avec 3 valeurs, que voulez mettre à jour, même si vous mettez à jour tous les trois, avec des opérations atomiques, ces trois opérations indépendantes, ainsi qu'un lecteur peut voir la structure, avec une valeur déjà en cours de mise à jour et deux pas en cours de mise à jour. Ici, vous aurez besoin d'un verrou si vous devez vous assurer, le lecteur voit toutes les valeurs dans la structure, soit l'ancienne ou la nouvelle valeur.

Une manière de faire de serrures échelle beaucoup mieux est d'utiliser R/W serrures. Dans de nombreux cas, les mises à jour de données sont plutôt rares (les opérations d'écriture), mais l'accès aux données est très fréquente (de la lecture des données), pensez collections (tables de hachage, arbres). Dans ce cas, R/W verrous acheter vous un énorme gain de performance, autant de fils peuvent tenir une lecture de verrouillage en même temps (ils ne vont pas se bloquer les uns les autres) et que si un thread veut un verrou d'écriture, tous les autres threads sont bloqués pour le moment la mise à jour est effectuée.

La meilleure façon d'éviter thread-problèmes est de ne pas partager toutes les données sur les threads. Si chaque thread traite la plupart du temps avec des données aucun autre thread n'a accès, vous n'aurez pas besoin de verrouillage pour que les données à tous (aussi pas d'opérations atomiques). Donc, essayez de partager que de peu de données que possible entre les threads. Ensuite, vous avez seulement besoin d'un moyen rapide pour déplacer des données entre threads, si vous avez vraiment pour (CCI, Entre le Thread de Communication). Selon votre système d'exploitation, la plate-forme et du langage de programmation (malheureusement, vous nous avez dit ni l'un ni l'), diverses méthodes puissantes pour le CCI pourrait exister.

Et enfin, une autre astuce pour travailler avec des données partagées, mais sans verrouillage est de s'assurer que les threads n'ont pas accès aux mêmes pièces que les données partagées. E. g. si deux threads partagent un tableau, mais on ne pourra y accéder même, l'autre seulement bizarre index, vous n'avez pas besoin de verrouillage. Ou si les deux partagent le même bloc de mémoire et on n'utilise que la moitié supérieure, l'autre seulement l'un en bas, vous n'avez pas besoin de verrouillage. Si ce n'est pas dit, ce qui se traduira par de bonnes performances, surtout pas sur les Processeurs multi-core. Les opérations d'écriture d'un thread à ce partage de données (exécution d'un seul cœur) peut forcer le cache pour être vidées pour un autre thread (en cours d'exécution sur une autre base) et ces vidages de cache sont souvent le goulot de la bouteille pour multithread applications en cours d'exécution sur le moderne, les Processeurs multi-core.

12voto

pb. Points 4609

Il est difficile d'écrire du code sans verrou thread-safe; mais cet article de Herb Sutter vous aidera à démarrer.

10voto

felixg Points 866

Comme mon professeur (Nir Shavit de "l'Art de La Programmation Multiprocesseur") dit à la classe: Merci de ne pas. La raison principale est la capacité de test pas de test de code de synchronisation. Vous pouvez exécuter des simulations, vous pouvez même le stress test. Mais c'est l'approximation au mieux. Ce que vous avez vraiment besoin est mathématique de preuve de correction. Et très peu capables de les comprendre, encore moins de les écrire. Donc, comme d'autres l'ont dit: l'utilisation des bibliothèques existantes. Joe Duffy blog enquêtes de certaines techniques (article 28). Le premier que vous devriez essayer est l'arbre-fractionnement - break pour les petites tâches et de les combiner.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X