mutex è usato per evitare race condition tra più thread.
mentre il semaforo viene utilizzato come elemento di sincronizzazione utilizzato su più processi.
mutex non può essere sostituito con il semaforo binario poiché un processo attende il semaforo mentre un altro processo rilascia il semaforo. Nel caso in cui mutex sia l'acquisizione che il rilascio sono gestiti dallo stesso.
Parlerò di Mutex vs Binary-Semaphore. Ovviamente usi mutex per impedire che i dati in un thread siano accessibili da un altro thread allo stesso tempo.
(Supponi di aver appena chiamato lock() e di essere in procinto di accedere a un dato. Ciò significa che non ti aspetti che nessun altro thread (o un'altra istanza dello stesso codice thread) acceda agli stessi dati bloccati dal stesso mutex. Cioè, se è lo stesso codice thread che viene eseguito su un'istanza di thread diversa, colpisce il blocco, allora lock() dovrebbe bloccare il flusso di controllo.)
Questo si applica a un thread che utilizza un codice thread diverso, che accede anche agli stessi dati e che è anch'esso bloccato dallo stesso mutex.
In questo caso, sei ancora in fase di accesso ai dati e potresti impiegare, diciamo, altri 15 secondi per raggiungere lo sblocco del mutex (in modo che l'altro thread che viene bloccato nel blocco del mutex si sblocchi e consenta al controllo di accedere ai dati).
Consenti mai a un altro thread di sbloccare solo lo stesso mutex e, a sua volta, consenti al thread che è già in attesa (bloccante) nel blocco del mutex di sbloccare e accedere ai dati? (Spero che tu abbia capito quello che sto dicendo qui.)
Secondo la definizione universale concordata,
- con "mutex" questo non può accadere. Nessun altro thread può sbloccare il blocco nel tuo thread
- con "binario-semaforo" questo può accadere. Qualsiasi altro thread può sbloccare il lucchetto nel tuo thread
Quindi, se sei molto attento all'uso del semaforo binario invece del mutex, allora dovresti stare molto attento nello "scoping" dei blocchi e degli sblocchi, voglio dire, che ogni flusso di controllo che colpisce ogni blocco dovrebbe colpire una chiamata di sblocco e anche non dovrebbe esserci alcun "primo sblocco", piuttosto dovrebbe essere sempre "primo blocco".
L'esempio della toilette
Mutex:
È una chiave per una toilette. Una persona può avere la chiave - occupare il bagno - al momento. Al termine, la persona dà (libera) la chiave alla persona successiva in coda.
"I mutex sono in genere utilizzati per serializzare l'accesso a una sezione di codice rientrante che non può essere eseguito contemporaneamente da più di un thread. Un oggetto mutex consente solo un thread in una sezione controllata, costringendo altri thread che tentano di ottenere l'accesso a quella sezione attendere che il primo thread sia uscito da quella sezione."
(Un mutex è in realtà un semaforo con valore 1.)
Semaforo:
È il numero di chiavi del bagno identiche gratuite. Ad esempio, supponiamo di avere quattro bagni con serrature e chiavi identiche. Il conteggio del semaforo - il conteggio delle chiavi - è impostato a 4 all'inizio (tutti e quattro i servizi igienici sono liberi), quindi il valore del conteggio viene decrementato man mano che le persone entrano. Se tutti i servizi igienici sono pieni, ad es. non sono rimaste chiavi libere, il conteggio del semaforo è 0. Ora, quando l'eq. una persona esce dal bagno, il semaforo viene aumentato a 1 (una chiave libera) e consegnato alla persona successiva in coda.
"Un semaforo limita il numero di utenti simultanei di una risorsa condivisa fino a un numero massimo. I thread possono richiedere l'accesso alla risorsa (decrementando il semaforo) e possono segnalare che hanno terminato di utilizzare la risorsa (incrementando il semaforo)."
Fonte
i semafori hanno un contatore sincronizzato ei mutex sono solo binari (vero/falso).
Un semaforo viene spesso utilizzato come meccanismo definitivo per rispondere a quanti elementi di una risorsa sono in uso, ad esempio un oggetto che rappresenta n thread di lavoro potrebbe utilizzare un semaforo per contare quanti thread di lavoro sono disponibili.
La verità è che puoi rappresentare un semaforo da un INT sincronizzato da un mutex.