2010-07-19 5 views
6

Ich habe C# für die letzten paar Jahre verwendet und ich bin derzeit Bugfixing in C++. In C# könnte ich Sperre für ein Objekt verwenden, um meinen Code Thread-sicher mit zu machen:Automatisches Sperren/Entsperren mit dem Bereich in C++ (von C# Hintergrund)

lock(lockObject) 
{ 
    // Do some work 
} 

Dies würde Entsperren der lockOject wenn es eine Ausnahme innerhalb der

// Do some work war Gibt es etwas ähnliches in C++? Im Moment kann ich entweder denken:

// Code 
{ 
    AutoLock lock(lockObject); 
    // Do some work 
} 
// More Code 

Aber ich weiß nicht, wie die geschweiften Klammern nur Umfang meines AutoLock. Im Moment habe ich so mache:

AutoLock lock(lockObject); 
// Do some work 
lock.Unlock(); 

und Abwickeln Release lassen Ausnahme die Sperre, wenn es eine Ausnahme in //Do some work.

Was ich gerade mache funktioniert, aber ich frage mich, ob es einen besseren Weg gibt, danke.

+0

_Aber ich mag die geschweiften Klammern nicht, nur um meine 'AutoLock' zu erfassen._ Abgesehen von ihrer Platzierung, wie unterscheiden sie sich von dem, was in C# getan wird? –

+0

Mit C# ''using (..) {...}' und 'lock (...) {...}' können Sie sehen, was vor sich geht. Es fühlt sich einfach falsch an, nur ein leeres '{...}' zu haben, um einen lokalen Bereich zu erstellen, um 'Autolock' zu zerstören. – JLWarlow

+0

Das macht Sinn. Ein Vorteil von C++ ist, dass Sie nur einen Bereich benötigen, um mehrere Sperren zu bereinigen. Wenn ich mich richtig erinnere, kann man in C# Dinge wie 'lock (m0) {Sperre (m1) {Sperre (m2) {}}}' –

Antwort

8

Aber ich mag nicht die geschweiften Klammern, nur um meine AutoLock zu begrenzen.

So wird es in C++ gemacht.

Beachten Sie, dass Sie für jedes AutoLock keinen separaten Bereichsblock benötigen; Folgendes ist auch in Ordnung:

{ 
    AutoLock lock1; 
    AutoLock lock2; 
    // more code goes here 
} // lock2 gets destroyed, then lock1 gets destroyed 

Es muss keinen separaten Rahmen Block entweder; Wenn Sie etwas in einer Funktion sperren und nicht erst entsperren müssen, bis die Funktion zurückkehrt, können Sie einfach den Funktionsumfang verwenden, um die Sperre einzuschränken. Wenn Sie während einer Iteration in einem Schleifenblock etwas sperren, können Sie den Gültigkeitsbereich-Block der Schleife verwenden, um die Sperre einzuschränken.

Ihr Ansatz der manuellen Entsperrung des Mutex, wenn Sie damit fertig sind, ist in Ordnung, aber es ist nicht idiomatische C++ und ist nicht so klar. Es macht es schwieriger herauszufinden, wo der Mutex freigeschaltet ist (vielleicht nicht viel härter, aber härter als nötig).

+0

Re: Manuelle Entsperrung. Es stimmt, es war keine ideale Wahl. Ich habe intelligente Zeiger für Schnittstellen verwendet, die Sie '.Release()' lassen, aber automatisch freigeben, wenn sie außerhalb des Bereichs sind. Es ist schon eine ganze Weile her, seit ich in C++ programmiert habe, vielleicht habe ich etwas vergessen/verpasst, das zu dem passt, was ich suchte. Daher diese Frage. – JLWarlow

2

Ihre zweite Version ist in Ordnung. Ziehen Sie in Erwägung, Ihre Methode zu splitten, wenn Sie zu viele Klammern haben, die nur für die bereichsspezifische Sperre bestimmt sind. Lesen Sie RAII, das ist das allgemeine Muster hinter dieser Technik, und es kann auf jede Art von Ressourcen-Management angewendet werden.

+0

Danke für den Link auf 'RAII', ich schaue jetzt auf intelligente Zeiger, um einen Speicherblock zu schützen, den mein Code empfängt. – JLWarlow