Wird der folgende Code zu einem Deadlock bei Verwendung von C # in .NET führen?
class MyClass
{
private object lockObj = new object();
public void Foo()
{
lock(lockObj)
{
Bar();
}
}
public void Bar()
{
lock(lockObj)
{
// Do something
}
}
}
Antworten:
Nein, nicht solange Sie dasselbe Objekt sperren. Der rekursive Code hat effektiv bereits die Sperre und kann daher ungehindert fortgesetzt werden.
lock(object) {...}
ist eine Abkürzung für die Verwendung der Monitor- Klasse. Wie Marc weist darauf hin ,Monitor
ermöglicht Neueintritt , so versucht auf einem Objekt Sperre wiederholt , auf dem der aktuelle Thread bereits eine Sperre hat wird gut funktionieren.Wenn Sie anfangen, verschiedene Objekte zu sperren , müssen Sie vorsichtig sein. Achten Sie besonders auf:
Wenn Sie gegen eine dieser Regeln verstoßen, werden Sie garantiert irgendwann Deadlock-Probleme bekommen .
Hier ist eine gute Webseite, die die Thread-Synchronisation in .NET beschreibt: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/
Sperren Sie außerdem so wenige Objekte wie möglich gleichzeitig. Erwägen Sie, wenn möglich, grobkörnige Schlösser anzubringen. Die Idee ist, dass Sie dies tun können, wenn Sie Ihren Code so schreiben können, dass ein Objektdiagramm vorhanden ist und Sie Sperren für die Wurzel dieses Objektdiagramms erwerben können. Dies bedeutet, dass Sie eine Sperre für dieses Stammobjekt haben und sich daher nicht so sehr um die Reihenfolge kümmern müssen, in der Sie Sperren erwerben / freigeben.
(Ein weiterer Hinweis: Ihr Beispiel ist technisch nicht rekursiv. Damit es rekursiv ist,
Bar()
muss es sich selbst aufrufen, normalerweise als Teil einer Iteration.)quelle
Nun,
Monitor
erlaubt Wiedereintritt, so dass Sie sich nicht selbst blockieren können ... also nein: es sollte nicht tunquelle
Wenn ein Thread bereits eine Sperre hält, blockiert er sich nicht. Das .Net-Framework stellt dies sicher. Sie müssen nur sicherstellen, dass zwei Threads nicht versuchen, dieselben zwei Sperren außerhalb der Reihenfolge durch beliebige Codepfade zu erhalten.
Derselbe Thread kann dieselbe Sperre mehrmals erwerben, Sie müssen jedoch sicherstellen, dass Sie die Sperre genauso oft freigeben, wie Sie sie erwerben. Solange Sie das Schlüsselwort "lock" verwenden, geschieht dies natürlich automatisch.
quelle
Nein, dieser Code hat keine toten Sperren. Wenn Sie wirklich am einfachsten einen Deadlock erstellen möchten, sind mindestens 2 Ressourcen erforderlich. Betrachten Sie den Hund und das Knochenszenario. 1. Ein Hund hat die volle Kontrolle über 1 Knochen, sodass jeder andere Hund warten muss. 2. Es sind mindestens 2 Hunde mit 2 Knochen erforderlich, um einen Deadlock zu erzeugen, wenn sie ihre Knochen sperren und auch andere Knochen suchen.
.. so weiter und so fort n Hunde und m Knochen und verursachen anspruchsvollere Deadlocks.
quelle