Ich sehe, dass wir für die Verwendung von Objekten, die nicht threadsicher sind, den Code mit einer Sperre wie folgt umschließen:
private static readonly Object obj = new Object();
lock (obj)
{
// thread unsafe code
}
Was passiert also, wenn mehrere Threads auf denselben Code zugreifen (nehmen wir an, dass er in einer ASP.NET-Webanwendung ausgeführt wird)? Sind sie in der Warteschlange? Wenn ja, wie lange werden sie warten?
Welche Auswirkungen hat die Verwendung von Sperren auf die Leistung?
Antworten:
Die
lock
Anweisung wird von C # 3.0 wie folgt übersetzt:In C # 4.0 hat sich dies geändert und wird nun wie folgt generiert:
Sie können weitere Informationen über das finden , was
Monitor.Enter
tut hier . So zitieren Sie MSDN:Die
Monitor.Enter
Methode wird unendlich warten; es wird keine Zeitüberschreitung geben.quelle
obj
ohne dass das gesamte System blockiert.lock
Anweisung und des Monitors: Damit Sie eine Operation in einem Thread ausführen können, ohne sich Sorgen machen zu müssen, dass ein anderer Thread sie durcheinander bringt.Es ist einfacher als Sie denken.
Laut Microsoft : Das
lock
Schlüsselwort stellt sicher, dass ein Thread keinen kritischen Codeabschnitt eingibt, während sich ein anderer Thread im kritischen Abschnitt befindet. Wenn ein anderer Thread versucht, einen gesperrten Code einzugeben, wartet er blockiert, bis das Objekt freigegeben wird.Das
lock
Schlüsselwort wirdEnter
am Anfang des Blocks undExit
am Ende des Blocks aufgerufen.lock
Das Schlüsselwort behandelt tatsächlich dieMonitor
Klasse am Backend.Zum Beispiel:
Im obigen Code betritt der Thread zuerst einen kritischen Abschnitt und wird dann gesperrt
obj
. Wenn ein anderer Thread versucht einzutreten, versucht er auch zu sperrenobj
, was bereits vom ersten Thread gesperrt ist. Der zweite Thread muss warten, bis der erste Thread freigegeben istobj
. Wenn der erste Thread verlässt, wird ein anderer Thread gesperrtobj
und tritt in den kritischen Bereich ein.quelle
Nein, sie stehen nicht in der Warteschlange, sie schlafen
Eine Sperranweisung des Formulars
wobei x ein Ausdruck eines Referenztyps ist, ist genau äquivalent zu
Sie müssen nur wissen, dass sie aufeinander warten und nur ein Thread zum Sperren des Blocks eingeht, die anderen warten ...
Monitor ist vollständig in .net geschrieben, so dass es schnell genug ist. Weitere Informationen finden Sie in der Klasse Monitor mit Reflektor
quelle
lock
Anweisung ausgegebeneSperren verhindern, dass andere Threads den im Sperrblock enthaltenen Code ausführen. Die Threads müssen warten, bis der Thread im Sperrblock abgeschlossen ist und die Sperre aufgehoben wird. Dies wirkt sich negativ auf die Leistung in einer Multithread-Umgebung aus. Wenn Sie dies tun müssen, sollten Sie sicherstellen, dass der Code innerhalb des Sperrblocks sehr schnell verarbeitet werden kann. Sie sollten versuchen, teure Aktivitäten wie den Zugriff auf eine Datenbank usw. zu vermeiden.
quelle
Die Auswirkungen auf die Leistung hängen von der Art und Weise ab, wie Sie sperren. Eine gute Liste der Optimierungen finden Sie hier: http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/
Grundsätzlich sollten Sie versuchen, so wenig wie möglich zu sperren, da dadurch Ihr Wartecode in den Ruhezustand versetzt wird. Wenn Sie umfangreiche Berechnungen oder lang anhaltenden Code (z. B. das Hochladen von Dateien) in einer Sperre haben, führt dies zu einem enormen Leistungsverlust.
quelle
do { oldValue = thing; newValue = updated(oldValue); } while (CompareExchange(ref thing, newValue, oldValue) != oldValue
]. Die größte Gefahr besteht darin, dass es schwierig sein kann, den Code anzupassen, wenn sich die Anforderungen über das hinaus entwickeln, was mit solchen Techniken möglich ist.Der Teil in der lock-Anweisung kann nur von einem Thread ausgeführt werden, sodass alle anderen Threads unbegrenzt darauf warten, dass der Thread, der die Sperre hält, beendet wird. Dies kann zu einem sogenannten Deadlock führen.
quelle
Die
lock
Anweisung wird in Aufrufe derEnter
undExit
-Methoden von übersetztMonitor
.Die
lock
Anweisung wartet auf unbestimmte Zeit, bis das Sperrobjekt freigegeben wird.quelle
Sperre ist eigentlich versteckte Monitor- Klasse.
quelle