2010-01-05 20 views
12

Dans .NET le mot-clé lock est le sucre syntaxique autour Monitor.Enter et Monitor.Exit, donc on peut dire que ce codeQuand utiliser le verrouillage vs MemoryBarrier dans .NET

lock(locker) 
{ 
    // Do something 
} 

est le même que

Monitor.Enter(locker); 
try 
{ 
    // Do Something 
} 
finally 
{ 
    Monitor.Exit(locker); 
} 

Cependant, le .NET Framework inclut également la classe MemoryBarrier qui fonctionne d'une manière similaire

Thread.MemoryBarrier(); 
//Do something 
Thread.MemoryBarrier(); 

Je suis confus comme quand je voudrais utiliser Thread.MemoryBarrier sur la version lock/Monitor? Je suis rendu encore plus confus par a Threading Tutorial qui déclare qu'ils fonctionnent le même. Dans la mesure où je peux voir la différence visible n'a pas besoin d'un objet de verrouillage, je suppose qu'en utilisant Monitor vous pouvez faire quelque chose à travers les threads MemoryBarrier sur un seul thread. Mon instinct me dit qu'une autre différence clé est MemoryBarrier est pour les variables seulement et pas pour les méthodes.

Enfin, ce n'est pas lié à la question existante When to use ‘volatile’ or ‘Thread.MemoryBarrier()’ in threadsafe locking code? (C#), car cela se concentre sur le mot-clé volatile dont je comprends l'utilisation.

Répondre

22

À mon avis, vous devriez presque jamais utiliser Thread.MemoryBarrier. Ceci est utilisé pour code sans verrou - en s'assurant que les modifications apportées à un thread sont visibles à l'autre sans encourir le coût d'un verrou. Il fait pas synchronisation de thread de contrôle, contrairement à . Je ne vois pas où dans le tutoriel de Joe, il dit que MemoryBarrier "fonctionne de la même manière" que lock. Pourriez-vous expliquer d'où exactement vous ressentez cette impression? À mon avis, le code sans verrouillage de bas niveau est trop difficile pour presque n'importe qui d'autre que les développeurs dont la compétence principale est la simultanéité. Si je veux écrire du code sans verrou, je vais utiliser des blocs de construction de plus haut niveau construits par ces développeurs (comme les extensions parallèles dans .NET 4.0) plutôt que d'essayer de lancer le mien.

À titre d'exemple, j'ai récemment eu mes yeux ouverts au sens précis de volatile qui n'est pas « toujours lu de la mémoire principale, toujours écrire directement dans la mémoire principale ». (Mon propre tutoriel de threading a toujours cette explication pour le moment - quelque chose que je dois corriger à un moment donné.) It's far more subtle than that. Cela signifie que certains de mes utilisations précédentes de volatile peuvent être incorrectes.

+0

Dans le didacticiel de Joe (sur la page je lie à), recherchez «Barrières de mémoire et verrouillage». Un court paragraphe indique qu'elles sont équivalentes «si nous ignorons la garantie d'exclusion mutuelle d'un verrou». –

+1

Cependant, ignorer l'exclusion mutuelle rend la comparaison inutile car elle fait partie intégrante des verrous – Grizzly

+1

@Grizzly: La comparaison n'est pas inutile - elle est utile en termes de * clôtures *. Mais ce n'est pas la même chose que de dire que les deux choses «fonctionnent de la même manière» - parce que la garantie d'exclusion mutuelle est le principal point de blocage. –