2015-08-04 2 views
5

Sono abbastanza nuovo alla concorrenza e ho difficoltà a decidere come utilizzare i mutex. Al momento sono cosparsi di tutto il mio codice in cui interagiscono due thread. Questo uso di mutex sarebbe appropriato?Mutex per tipi di dati semplici

class Foo 
{ 
public: 
    void SetMember(int n) { AcquireMutex(..); n_ = n; ReleaseMutex(...);} 
private: 
    Thread() 
    { 
     while(1) 
     { 
     AcquireMutex(..); 
     // Do something with n_ 
     ReleaseMutex(...); 
     } 
    } 
}; 

ho un bel paio di membri di dati che possono essere letti e impostati dall'esterno da un thread diverso, e mi sto trovando che fosse un mal di testa per tenere traccia di tutte le acquisizione e rilascio del mutex.

+0

Nome del mutex dopo che la variabile è protetta ad es. n_mutex (per n). Inoltre è necessario considerare cosa fare se è necessario aggiornare più di una variabile quando si modifica lo stato del proprio oggetto di classe, ad es. impostando una dimensione su 0 e cancellando un puntatore quando si ripristina qualcosa. Considera anche l'atomica per i tipi primitivi. –

+0

Non ho accesso a C++ 11, il che significa che non posso usare l'atomica? –

+0

@ Q-bertsuit Non è possibile utilizzare gli atomici della libreria standard, ma se si utilizza C++/CLI, penso che Microsoft abbia le proprie operazioni atomiche – KABoissonneault

risposta

3

La mutazione dei tipi primitivi non è garantita come thread-safe o, più specificamente, atomica. Infatti, se si guarda in <atomic> noterete che ci sono diverse specializzazioni, tra cui std::atomic_int.

Da cppreference

oggetti di tipi atomici sono l'unico C++ oggetti che sono esenti da razze dati; cioè, se un thread scrive su un oggetto atomico mentre un altro thread legge da esso, il comportamento è ben definito.

Per rispondere in modo specifico alla domanda sull'uso di mutex, sì, il tuo uso di mutex va bene nel tuo esempio. In generale, si desidera mantenere un mutex il più corto possibile. In altre parole, se hai una funzione che fa molto lavoro, blocca solo il mutex attorno al codice non-threadsafe, quindi sbloccalo non appena il codice è protetto da un thread in seguito.

+0

Quindi qualsiasi dato che può essere letto/scritto da due thread e non è atomico deve usare mutex (o semplici, ecc.)? –

+0

@ I mutex di Q-bertsuit eseguono 2 lavori, (1) bloccando la memoria (2). –

+0

Grazie. Come una domanda a parte; dovrei usare diversi mutex per dati diversi (uno per foo_, uno per bar_ ecc.) o è un singolo mutex fine? –

1

Questo approccio di mutua esclusione è piuttosto ingenuo e non eviterà i problemi di deadlock e altri problemi con la concorrenza.

È necessario identificare esplicitamente le posizioni nel codice in cui gli accessi simultanei da parte di due processi causerebbero un problema e li proteggeranno in una sezione critica. E devi assicurarti di non permettere a due processi di avviare un'operazione che non possono completare a causa di un altro processo.

In altri luoghi, potrebbe non esserci alcuna necessità di protezione e l'attivazione di un mutex sarebbe eccessivo.

Molto spesso, l'atomicità è richiesta non per una singola variabile ma per un insieme di variabili accoppiate.