2015-05-12 10 views
11

Le variabili di condizione sono uno degli aspetti di C++ 11 Sto ancora lottando con un po '. Da quello che ho raccolto una variabile di condizione è molto simile a un semaforo.Perché una variabile di condizione ha bisogno di un lock (e quindi anche di un mutex)

Ma poi di nuovo, un semaforo non avrebbe bisogno di un blocco per funzionare. Una variabile di condizione fa. E una serratura a sua volta ha bisogno di un mutex. Quindi, al fine di utilizzare la funzionalità abbastanza semplice di un semaforo, ora dobbiamo non solo gestire una variabile di condizione. Ma anche un mutex e una serratura.

Quindi perché una variabile di condizione ha bisogno di questo? E quale funzionalità aggiunta viene fornita aggiungendo questo requisito?

+1

Il mutex è il blocco. Il lock della classe thread è solo un wrapper RAII attorno al mutex, quindi non è gestito ma usato localmente. – stefaanv

+0

correlati [Perché le funzioni delle variabili di condizione di pthreads richiedono un mutex?] (Http://stackoverflow.com/q/2763714/2069064) – Barry

+0

Correlato in modo tangenziale: è possibile implementare semafori in termini di mutex e variabili di condizione piuttosto facilmente. Le variabili di condizione sono solo una diversa primitiva in attesa; rendono molto più semplice aspettare le condizioni generali, espresse dal codice utente. – Mark

risposta

6

Le variabili di condizione sono generalmente utilizzate per segnalare un cambiamento di stato. Di solito è necessario un mutex per fare quel cambiamento, e il seguente segnale, atomico.

Un semaforo incapsula uno stato (una bandiera o un contatore) insieme al meccanismo di segnalazione. Una variabile di condizione è più primitiva, fornendo solo il segnale.

+2

Almeno in C++, non è necessario proteggere la segnalazione con un blocco. Infatti, a seconda di come l'implementazione gestisce la pianificazione del thread in attesa, potrebbe essere dannoso per le prestazioni eseguire la segnalazione all'interno del blocco. Mentre ci sono determinate condizioni in cui la logica del programma può fare affidamento sul fatto che lo stato cambia e la segnalazione avviene atomicamente, ciò non è in generale vero quando si utilizza una variabile di condizione. – ComicSansMS

+0

Non è il contrario? La variabile di condizione è un semaforo, su un mutex.Indicare se il mutex è di nuovo disponibile? Rendere il semaforo più primitivo. – laurisvr

+0

@laurisvr: No, un semaforo combina una bandiera/contatore atomico con un segnale, quindi non è primitivo. Una variabile di condizione è solo un segnale, che generalmente usi in combinazione con qualche altra cosa il cui stato cambia che vuoi segnalare. –

4

In generale, una volta segnalato che qualcosa è cambiato (tramite una variabile di condizione) è necessario un codice da eseguire per gestire tale modifica e tale codice deve leggere in modo sicuro i dati modificati. Se non hai un blocco associato al cv, il tuo thread in attesa sul cv potrebbe svegliarsi, quindi provare a (e fallire) ad acquisire il blocco associato ai dati e quindi dover cedere di nuovo. Con una combo CV/Lock il sistema sottostante può riattivare il thread solo se il thread può acquisire il lock pertinente come un'unità e quindi essere più efficiente.

È improbabile che un CV da solo sia utile in quanto non fornisce dati superiori al fatto che è stato segnalato. Se immagini usi di cv - come una lista concatenata thread-safe con produttori e consumatori, hai variabili che rappresentano {list, cv, lock}. In questo caso si prende il blocco, si modifica l'elenco, si rilascia il blocco e si segnala il cv. Sul filo del consumatore è molto probabile che tu debba prendere il lucchetto una volta segnalato per agire sulla lista, quindi avere il lucchetto acquisito una volta svegli dal cv che viene segnalato è una cosa buona.

Guarda qualcosa di simile su windows (:: CreateEvent) che sono cv senza il blocco implicito, un sacco di tempo in cui avranno un blocco associato a loro, ma semplicemente non integrati nell'utilizzo effettivo.

Sebbene questo non sia il motivo originale, è stata creata la variabile di condizione in pthreads (hanno utilizzato il blocco per proteggere il cv stesso che non è più necessario in C++) la ragione e l'utilità dei blocchi con cv è migrata a che cosa è in questo risposta.

Problemi correlati