Lorsque nous parlons de variables atomiques, telles que les atomic<>
de C ++ 11, est-il verrouillé? Ou lock-freeness est-il différent? Si je gère une file d'attente avec des variables atomiques, sera-t-elle plus lente qu'une file d'attente sans verrouillage?
Réponses
Trop de publicités?La norme ne précise pas si atomique objets sont sans verrouillage. Sur une plate-forme qui ne fournit pas sans verrouillage des opérations atomiques pour un type T, atomic<T>
objets peuvent être mises en œuvre à l'aide d'un mutex, qui ne serait pas sans verrouillage. Dans ce cas, tous les récipients à l'aide de ces objets dans leur mise en œuvre ne serait pas sans verrouillage soit.
La norme fournit un moyen de vérifier si un atomic<T>
variable est sans verrouillage: vous pouvez utiliser var.is_lock_free()
ou atomic_is_lock_free(&var)
. Ces fonctions sont garantis retourne toujours la même valeur pour le même type T
sur l'exécution du programme. Pour les types de base tels que l' int
, Il y a aussi des macros (par exemple, ATOMIC_INT_LOCK_FREE
), qui précisent les si sans verrouillage atomique accès à ce type n'est disponible.
Sans verrouillage s'applique généralement à des structures de données partagées entre plusieurs threads, où la synchronisation est pas d'exclusion mutuelle; l'intention est que tous les threads doivent continuer à faire une sorte de progrès au lieu de dormir sur un mutex.
atomic<T>
variables de ne pas utiliser des verrous (au moins où T
est nativement atomique sur votre plate-forme), mais ils ne sont pas sans verrouillage dans le sens ci-dessus. Vous pourriez utiliser dans la mise en œuvre d'un lock-conteneur gratuit, mais ils ne sont pas suffisants.
Par exemple, atomic<queue<T>>
ne serait pas tout à coup faire un normal std::queue
en un lock-libre de la structure de données. Vous pouvez, toutefois, de mettre en œuvre un véritable sans verrouillage atomic_queue<T>
dont les membres ont été atomic
.
Notez que même si atomic<int>
est nativement atomique et non émulé avec un verrou sur votre plate-forme, qui n'est pas sans verrouillage en aucune façon intéressante. Plaine int
est déjà sans verrouillage en ce sens: l' atomic<>
wrapper vous obtient le contrôle explicite de la mémoire de la commande, et l'accès à du matériel à des primitives de synchronisation.
Marketting et le facteur "cool" de côté, il ne fait pas une twopenny tirage au sort d'une différence si la magie C++ syntaxique (brun) de sucre finit par la mise en œuvre d'un bus direct de verrouillage ou un mutex (qui peut compter sur le bus de serrures mais, comme un commentateur l'a fait remarquer, profite de l'OS lui-même pour le faire d'une façon plus efficace), ou rien du tout si vous avez la malchance de s'exécuter sur un seul procesor architecture.
Mutex sont sémantiquement lock gratuit déjà. Ils mettent en œuvre tout ce dont vous pourriez rêver en termes de planification-la gentillesse, à savoir l'inversion de priorité de la manipulation et de la réentrée. Vous ne peut pas l'impasse sur un mutex (bon, en fait, vous pourriez si vous avez essayé très dur, mais aussi loin que la sécurisation d'une variable est concerné, vous n'aurez pas), et à l'aide d'un mutex sera de ne pas avoir plus notables effets secondaires sur les autres processus ou le système d'exploitation que d'un arrêt de bus verrouillé variable.
La seule différence est qu'un programmeur peut (par leur conception ou par erreur) détenir un mutex pour un temps déraisonnable, bien que tout aussi incompétents programmeur peut sondage sur une "Attente" sans variable et d'obtenir la même idiot résultats, avec une catastrophique bus ralentissement qui va mettre beaucoup plus de stress sur le système dans son ensemble que d'une mauvaise utilisation de mutex (OK, mon précédent allusion à un BSOD était juste un juvénile provokation, si j'ai toujours suspect certains pilotes peuvent ne pas réagir très gentiment à l'lourd de contention de bus). De toute façon, ce problème est vite résolu quand le mutex appels sont enroulées autour d'un linéaire de l'accès à une assez petite quantité de mémoire.
"Verrouiller libre" est de vendre des rêves de wanabee durs programmeurs. Je trouve assez amusant que d'un mécanisme qui indeeds s'appuie sur le verrouillage de la multiprocesseur bus pourrait être appelé comme ça.
Ce qu'est un "Lock gratuit" variable d'accès n'est harceler le matériel par la stérilisation du bus système de cache, interdisant l'accès au bus de planification, et plus généralement à la désactivation de tous les mécanismes qui permettent à votre moyenne multiprocesseur de bus pour faire un travail décent.
Chaque fois que vous accédez à un "Verrou libre" magie variable, vous êtes une battante poignée de sable dans le bus du contrôleur de roues dentées.
Comme tout simultanées mécanisme d'accès, bus à verrouillage de variables (désolé, je voulais dire "Verrouiller les variables libres") sont coûteux et peuvent avoir des effets secondaires négatifs qui sont extrêmement difficiles à prévoir ou même de diagnostiquer.
Aussi longtemps que vous êtes à l'aide de ces nouveaux brillant jouets comme vous le feriez pour les mutex, c'est à dire très peu et seulement pour quelques bonnes raisons (et non, le jeu de la super cool de M. d'attente gratuit n'est pas l'un d'eux), c'est la fin.
Mais si vous commencez à l'aspersion de bus de serrures de tous sur la place, ou (Dieu interdit!) bureaux de bus-verrouillé variables comme facile et bon marché de remplacement pour une bonne synchronisation des objets (ce que le super cool de M. d'attente gratuit pourrait appeler "le brassage de votre propre maison spinlocks en 3 étapes faciles"), vous ne gérer à son tour tout ce matériel de pointe votre code s'exécute dans un circa 1995 Pentium I de l'émulateur.