Ho una classe con thread da cui vorrei acquisire occasionalmente un puntatore una variabile di istanza. Vorrei che questo accesso fosse protetto da un mutex in modo che il thread fosse bloccato dall'accesso a questa risorsa fino a quando il client non ha finito con il suo puntatore.Come posso creare un puntatore intelligente che blocca e sblocca un mutex?
Il mio approccio iniziale a questo è di restituire una coppia di oggetti: uno un puntatore alla risorsa e uno un shared_ptr a un oggetto di blocco sul mutex. Questo shared_ptr contiene l'unico riferimento all'oggetto lock in modo che il mutex debba essere sbloccato quando esce dall'ambito. Qualcosa del genere:
void A::getResource()
{
Lock* lock = new Lock(&mMutex);
return pair<Resource*, shared_ptr<Lock> >(
&mResource,
shared_ptr<Lock>(lock));
}
Questa soluzione non è l'ideale perché richiede al client di trattenere l'intera coppia di oggetti. Comportamento come questo rompe il filo di sicurezza:
Resource* r = a.getResource().first;
Inoltre, la mia propria implementazione di questo è blocco critico e sto avendo difficoltà a determinare il motivo per cui, così ci possono essere altre cose che non va.
Quello che mi piacerebbe avere è un shared_ptr che contiene il blocco come variabile di istanza, collegandolo con i mezzi per accedere alla risorsa. Questo sembra qualcosa che dovrebbe avere un modello di progettazione stabilito, ma avendo fatto qualche ricerca sono sorpreso di trovare abbastanza difficile da trovare.
Le mie domande sono:
- C'è un'implementazione comune di questo modello?
- Ci sono problemi con il mettere un mutex in un shared_ptr che sto trascurando che impedisca questo pattern di essere diffuso?
- C'è una buona ragione per non implementare la mia classe shared_ptr per implementare questo pattern?
(NB sto lavorando su una base di codice che utilizza Qt, ma purtroppo non è possibile utilizzare spinta in questo caso. Tuttavia, le risposte che coinvolgono spinta sono ancora di interesse generale.)
Entrambe le risposte del riv e Jonanthan Wakely sono interessanti e degne di essere seguite. Vado con Riz solo perché è bello avere un codice completo di modifica collaborativa in una risposta. –