2010-07-19 15 views
6

Utilizzo C# da alcuni anni e attualmente risolvo bug in C++. In C# ho potuto utilizzare il blocco su un oggetto per fare il mio filo di codice sicuro con:Blocco/sblocco automatico utilizzando scope in C++ (da sfondo C#)

lock(lockObject) 
{ 
    // Do some work 
} 

Ciò sbloccare il lockOject se ci fosse un'eccezione all'interno della // Do some work

C'è qualcosa di simile in C++? Al momento mi viene in mente uno:

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

Ma non mi piace le parentesi graffe solo a scopo mia AutoLock. Al momento sto facendo:

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

E lasciando eccezione rilascio svolgimento il blocco se c'è un'eccezione in //Do some work.

Quello che sto facendo al momento funziona, ma mi chiedo se c'è un modo migliore, grazie.

+0

_Ma non mi piacciono le parentesi graffe solo per eseguire il mio 'AutoLock'._ A parte il loro posizionamento, come sono differenti da quello che viene fatto in C#? –

+0

Con l'uso di C# (..) {...} 'e' lock (...) {...} 'puoi vedere cosa sta succedendo. Mi sembra semplicemente sbagliato avere semplicemente '{...}' per creare un ambito locale per effettuare la distruzione di 'Autolock'. – JLWarlow

+0

Questo ha senso. Un vantaggio del modo di fare C++ è che è necessario un solo scope per ripulire più blocchi; se ricordo bene, in C# puoi finire con cose come 'lock (m0) {lock (m1) {lock (m2) {}}}' –

risposta

8

Ma non mi piacciono le parentesi graffe solo per il mio telescopio AutoLock.

Ecco come è fatto in C++.

Nota che non è necessario disporre di un blocco di ambito separato per ogni AutoLock; anche il seguente è corretto:

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

Non deve essere un blocco di ambito separato; se si blocca qualcosa in una funzione e non è necessario sbloccarlo finché la funzione non ritorna, è possibile utilizzare semplicemente l'ambito della funzione per vincolare il blocco. Allo stesso modo, se si blocca qualcosa durante ogni iterazione in un blocco di loop, è possibile utilizzare il blocco di ambito del ciclo per vincolare il blocco.

Il tuo approccio di sbloccare manualmente il mutex quando hai finito con esso va bene, ma non è un C++ idiomatico e non è così chiaro. Rende più difficile capire dove è stato sbloccato il mutex (non molto più difficile, forse, ma più difficile di quanto dovrebbe essere).

+0

Re: sblocco manuale. È vero, non era una scelta ideale. Ho usato dei puntatori intelligenti per le interfacce che ti permettono di '.Release()', ma rilascerà automaticamente quando fuori dal campo di applicazione. È passato un po 'di tempo da quando stavo codificando in C++, potrei aver dimenticato/perso qualcosa che si adattava a quello che stavo cercando. Quindi questa domanda. – JLWarlow

2

La tua seconda versione va bene. Prendi in considerazione di suddividere il tuo metodo se hai troppe parentesi solo per il blocco dell'ambito. Leggi su RAII, questo è lo schema generale alla base di questa tecnica e può essere applicato a qualsiasi tipo di gestione delle risorse.

+0

Grazie per il collegamento su "RAII", ora sto guardando puntatori intelligenti per proteggere un blocco di memoria che il mio codice riceve. – JLWarlow