2010-01-05 6 views
12

In .NET das lock Schlüsselwort ist syntaktischer Zucker um Monitor.Enter und Monitor.Exit, so dass Sie, dass dieser Code sagen könnenWenn die Sperre verwenden vs Memory in .NET

lock(locker) 
{ 
    // Do something 
} 

die gleichen wie

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

Allerdings enthält das .NET-Framework auch die MemoryBarrier-Klasse, die auf ähnliche Weise funktioniert.

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

Ich bin verwirrt, wenn ich Thread.MemoryBarrier über die lock/Monitor Version verwenden möchte? Ich bin noch mehr durch a Threading Tutorial verwirrt, die besagt, dass sie die gleichen funktionieren.

Soweit ich sehen kann, benötigt der sichtbare Unterschied kein Sperrobjekt, was ich denke, dass mit Monitor Sie etwas über Threads tun können, wo MemoryBarrier auf einem einzigen Thread ist.

Mein Darm sagt mir, dass ein weiterer wichtiger Unterschied ist MemoryBarrier ist nur für Variablen und nicht für Methoden.

Schließlich ist dies nicht auf die bestehende Frage When to use ‘volatile’ or ‘Thread.MemoryBarrier()’ in threadsafe locking code? (C#), wie das auf das volatile Schlüsselwort bezieht, die ich verstehe seine Verwendung von.

Antwort

22

Aus meiner Sicht sollten Sie fast nie verwenden Thread.MemoryBarrier. Dies wird für sperrfreien Code verwendet - stellen Sie sicher, dass Änderungen, die an einem Thread vorgenommen wurden, für einen anderen sichtbar sind, ohne dass die Kosten für eine Sperre anfallen. Es tut nicht Steuerelement Thread-Synchronisierung, im Gegensatz zu lock. Ich sehe nicht, wo in Joes Tutorial er sagt, dass "funktioniert das gleiche" wie lock. Können Sie erklären, woher Sie genau diesen Eindruck haben?

Meiner Ansicht nach ist Lockcode für Low-Level zu schwierig für fast jeden anderen als Entwickler, deren Hauptfertigkeit Parallelität ist. Wenn ich etwas Lock-Free-Code schreiben möchte, werde ich höhere Bausteinen von diesen Entwicklern (wie Parallel Extensions in .NET 4.0) verwenden, anstatt zu versuchen, meine eigene zu rollen.

Nur als Beispiel, ich habe vor kurzem meine Augen auf die genaue Bedeutung des volatile geöffnet, die ist nicht „immer aus dem Hauptspeicher gelesen, immer direkt in den Hauptspeicher schreiben“. (Mein eigenes Threading-Tutorial hat immer noch diese Erklärung im Moment - etwas, das ich irgendwann beheben muss.) It's far more subtle than that. Dies bedeutet, dass einige meiner früheren Verwendungen volatile möglicherweise falsch sind.

+0

In Joes Tutorial (auf der Seite, die ich verlinke) nach 'Speicherbarrieren und Sperren' gibt es einen kurzen Absatz, der besagt, dass sie äquivalent sind, "wenn wir die gegenseitige Ausschlussgarantie einer Sperre ignorieren". –

+1

Aber ignorieren den gegenseitigen Ausschluss macht den Vergleich Art von sinnlos, da das ein integraler Bestandteil der Schlösser ist – Grizzly

+1

@Grizzly: Der Vergleich ist nicht sinnlos - es ist nützlich in Bezug auf * Zäune *. Aber das ist nicht dasselbe wie zu sagen, dass die zwei Dinge "gleich funktionieren" - weil die gegenseitige Ausschlussgarantie der Hauptpunkt der Sperrung ist. –