Sollen Sperren und Mutexe in C # zusammen verwendet werden?

8

Wäre das nicht übertrieben und nur einer davon notwendig? Ich habe gesucht und gefunden verschiedene Beiträge über gegenseitige Ausgrenzung und sperrt in C # hier und hier .

Beispiel:
In unserer App haben wir eine Funktion, die mehrere Reconnection-Threads abspinnt. Innerhalb dieses Threads verwenden wir Mutex und lock . Würde nicht lock den Zugriff auf diesen Codeabschnitt blockieren und verhindern, dass connect von einem anderen Thread aktualisiert wird?

%Vor%

Weitere Informationen:
Dies ist in einem ASP.NET WebService, der nicht in einem Web Garden ausgeführt wird.

    
Jeremy Cron 13.03.2009, 15:13
quelle

4 Antworten

11

Dieser Mutex (weil er einen Namen hat) stoppt jeden Prozess auf demselben Computer, der darauf zugreift, während die Sperre nur andere Threads im selben Prozess stoppt. Ich kann nicht anhand dieses Codebeispiels sehen, warum Sie beide Arten von Sperren benötigen. Es scheint eine gute Übung zu sein, die einfache Sperre für eine kurze Zeit zu halten - aber dann ist der viel schwerere Interprozess-Mutex für eine wahrscheinlich längere (wenn auch überlappende) Periode gesperrt! Wäre einfacher, einfach den Mutex zu verwenden. Und vielleicht um herauszufinden, ob eine Interprozesssperre wirklich notwendig ist.

Übrigens ist catch {} in diesem Szenario absolut falsch. Sie sollten finally { /* release mutex */ } verwenden. Sie sind sehr verschieden. Der Catch schluckt weit mehr Arten von Ausnahme als es sollte, und verursacht auch verschachtelte schließlich Handler als Reaktion auf Low-Level-Ausnahmen wie Speicherbeschädigung, Zugriffsverletzung, usw. Also statt:

%Vor%

Sie sollten:

%Vor%

Und wenn es bestimmte Ausnahmen gibt, von denen Sie wiederherstellen können, könnten Sie sie abfangen:

%Vor%     
Daniel Earwicker 13.03.2009, 15:17
quelle
3

"lock" ist im Grunde nur eine syntaktische Zucker für Montor.Enter / Exit. Mutex ist eine Mehrfachprozesssperre.

Sie haben ein sehr unterschiedliches Verhalten. Es ist nichts falsch daran, beide in der gleichen Anwendung oder den gleichen Methoden zu verwenden, da sie dazu gedacht sind, verschiedene Dinge zu blockieren.

Aber in Ihrem Fall denke ich, dass Sie besser in Semaphore und Monitor schauen können. Es klingt nicht so, als müssten Sie Prozesse blockieren, daher sind sie in dieser Situation wahrscheinlich die bessere Wahl.

    
Reed Copsey 13.03.2009 15:21
quelle
2

Wie andere darauf hingewiesen haben, sperrt der Mutex alle Prozesse und die lokale Sperre (Monitor) sperrt nur die Threads, die dem aktuellen Prozess gehören. Jedoch ...

Der Code, den du gezeigt hast, hat einen ziemlich ernsten Fehler. Offenbar geben Sie den Mutex am Ende bedingungslos frei (d. H.% Co_de%), aber der Mutex wird nur übernommen, wenn reconnectMutex.ReleaseMutex() site.ContainsKey() zurückgibt.

Wenn also true site.ContainsKey zurückgibt, wird das Freigeben des Mutex false auslösen, weil der aufrufende Thread nicht den Mutex besitzt.

    
Jim Mischel 13.03.2009 19:12
quelle
1

Sie haben nicht genug Informationen gegeben, um das wirklich zu beantworten. Wie bereits von Earwicker angegeben, ermöglicht Ihnen ein Mutex eine Synchronisation über Prozesse hinweg. Wenn Sie also zwei Instanzen derselben App ausführen, können Sie den Zugriff serialisieren. Dies können Sie beispielsweise bei Verwendung externer Ressourcen tun.

Jetzt sperren Sie Site vor Sites vor Zugriff durch andere Threads in demselben Prozess. Dies kann abhängig davon sein, was andere Methoden / Threads tun. Nun, wenn dies der einzige Ort ist, an dem die Site gesperrt wird, dann denke ich, dass es Overkill ist.

    
JoshBerke 13.03.2009 15:22
quelle

Tags und Links