Credo che si possa avere un mutex dichiarato nella funzione chiamata stessa o può essere dichiarato membro della classe o globale. Qualcuno può spiegare per favore?
creazione di un nuovo mutex alla voce non protegge nulla.
se si stava considerando di dichiarare un mutex statico (o globale) per proteggere i membri non statici, quindi si può anche scrivere il programma come un programma a thread singolo (ok, ci sono alcuni casi d'angolo). un blocco statico bloccherebbe tutti i thread tranne uno (assumendo contest); equivale a "un massimo di un thread può operare nel corpo di questo metodo contemporaneamente". dichiarare un mutex statico per proteggere i dati statici va bene. come David Rodriguez - dribeas lo ha scritto succintamente nei commenti di un'altra risposta: "Il mutex dovrebbe essere al livello dei dati che vengono protetti".
si possibile dichiara una variabile membro per esempio, che potrebbe assumere la forma generalizzata:
class t_object {
public:
...
bool getData(t_data& outData) {
t_lock_scope lock(this->d_lock);
...
outData.set(someValue);
return true;
}
private:
t_lock d_lock;
};
questo approccio va bene, e in alcuni casi ideale. ha senso nella maggior parte dei casi quando si costruisce un sistema in cui le istanze intendono astrarre meccanismi di blocco ed errori dai propri clienti. uno svantaggio è che può richiedere più acquisizioni e in genere richiede meccanismi di blocco più complessi (ad esempio rientranti). da più acquisizioni: il cliente può sapere che un'istanza è utilizzata in un solo thread: perché bloccare in quel caso? così, un mucchio di piccoli metodi di sicurezza introdurranno un sacco di spese generali. con il blocco, si desidera entrare e uscire dalle aree protette appena possibile (senza introdurre molte acquisizioni), quindi le sezioni critiche sono spesso operazioni più grandi di quelle tipiche.
se l'interfaccia pubblica richiede questo blocco come argomento (come si vede nel tuo esempio), è un segnale che il disegno può essere semplificata privatizzando bloccaggio (rendendo la funzione dell'oggetto in modo sicuro filo, invece di passare la serratura come risorsa tenuta esternamente).
utilizzando un blocco esterno (o associato o associato), è possibile ridurre le acquisizioni (o il tempo totale bloccato). questo approccio consente anche di aggiungere il blocco a un'istanza dopo il fatto. consente inoltre al client di configurare il funzionamento del blocco. il client può utilizzare un numero inferiore di blocchi condividendoli (tra una serie di istanze). anche un semplice esempio di composizione può illustrare questo (supporto entrambi i modelli):
class t_composition {
public:
...
private:
t_lock d_lock; // << name and data can share this lock
t_string d_name;
t_data d_data;
};
considerando la complessità di alcuni sistemi multithread, spingendo la responsabilità del corretto bloccaggio sul client può essere un pessima idea.
entrambi i modelli (vincolati e come variabile membro) possono essere utilizzati efficacemente. che è meglio in un dato scenario varia a seconda del problema.
È necessario aggiungere un esempio particolare in cui viene utilizzato. Probabilmente è dovuto alla semantica implementata nell'esempio e non è possibile rispondere a tutto il contesto (a meno che non si voglia generico * solo perché * o * potrebbe avere senso * risposte) –