PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C#]lock + SyncRoot vs. Mutex.WaitOne?


Gast
2006-11-06, 17:54:50
Hi Leute,

ich habe in der MSDN, genauer gesagt hier:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemcollectionssortedlistclasssyncroottopic.asp

folgendes Codebeispiel gefunden:

SortedList myCollection = new SortedList();
lock( myCollection.SyncRoot )
{
foreach ( Object item in myCollection )
{
// Insert your code here.
}
}

das so weit ich verstanden habe dazu dienen soll, die im lock-Block stehenden Operationen an der SortedList myCollection thread-sicher zu machen.
Aber hat das nicht die gleiche Wirkung wie diese Konstruktion:

SortedList myCollection = new SortedList();
Mutex myMutex = new Mutex;
myMutex.WaitOne();
foreach ( Object item in myCollection )
{
// Insert your code here.
}
myMutex.ReleaseMutex();

d.h. ein lock-Block übernimmt einfach die Funktion einer critical section?
Oder hat es mit dieser Synchronisation, die im lock-Block gemacht wird, etwas anderes auf sich?

Kabelsalat
2006-11-09, 14:33:10
Das C# lock-Schlüsselwort kapselt nur die Funktionalität der Monitor Klasse. Diese wird vom .Net Framework zu Verfügung gestellt und greift im Gegensatz zur Mutex-Klasse, die ungefähr den selben Funktionsumfang bietet, nur auf die CLR und nicht auf Betriebsystemfunktionen zurück. Somit ist auch die Performance der geringfügig besser und man sollte schon alleine deshalb der Monitor Klasse den Vorzug geben - einige Ausnahmen gibt es aber dennoch, so lässt sich nur Mutex prozessübergreifend verwenden (auch gemischt, managed und unmanaged).

Demirug
2006-11-09, 14:44:35
Lock hat noch einen Vorteil. Sollte es innerhalb des Codeblocks zu einer Exception kommen wird dafür gesorgt das der lock auf das Objekt wieder aufgehoben wird bevor die Exception weiter geworfen wird.

Kabelsalat
2006-11-09, 14:55:58
Obwohl ich dir vollkommen rechtgebe sollte noch try { .. } finally { .. } als Alternative genannt werden. Es ist auch möglich das C# using-Konstrukt zu missbrauchen: Ich habe mir etwa eine Klasse LockObject geschrieben, die etwa den selben Funktionsumfang wie die Monitor Klasse bietet, bei Erkennung eines Deadlock wird jedoch eine Exception geschmissen. Dort verwende ich folgende Syntax:


using (MyLockObject.Lock())
{

}


LockObject muss hierzu nur ein Objekt zurückliefern, das IDisposable implementiert: Ein Aufruf der zugehörigen Dispose-Methode sorgt nun automatisch zum Aufruf von LockObject.Unlock()...

Gast
2006-11-10, 14:57:22
Das C# lock-Schlüsselwort kapselt nur die Funktionalität der Monitor Klasse. Diese wird vom .Net Framework zu Verfügung gestellt und greift im Gegensatz zur Mutex-Klasse, die ungefähr den selben Funktionsumfang bietet, nur auf die CLR und nicht auf Betriebsystemfunktionen zurück. d.h. die CLR verfügt über eine eigene, von den Funktionen des OS unabhängige Thread-Synchronisierung? Wie funktioniert denn das?

Kabelsalat
2006-11-10, 22:10:26
Eine einfache Spinlock basierte Implementierung ist kein Hexenwerk... Sicher, das .Net Framework packt die Sache eleganter an, und dass in Teilen weiterhin OS- (bzw. LowLevel-) Funktionen genutzt werden ist auch klar, aber es macht einen großen Unterschied, ob die eigentliche Logik in der CLR oder im OS implementiert ist: In dieser hinsicht macht es sich Mutex besonders einfach, da lediglich .Net Interop (P/Invoke) benutzt wird um die entsprechenden WinAPI Funktionen aufzurufen.

Wenn dich Details interessieren, wäre die SSCLI evtl. etwas für dich (liefert sehr interessante Einblicke): http://www.microsoft.com/downloads/details.aspx?FamilyId=8C09FD61-3F26-4555-AE17-3121B4F51D4D&displaylang=en