Quando dovremmo usare il mutex e quando dovremmo usare il semaforo

Quando dovremmo usare il mutex e quando dovremmo usare il semaforo?

Ecco come ricordo quando usare cosa –

Semaforo: usa un semaforo quando tu (thread) vuoi dormire finché qualche altro thread ti dice di svegliarti. Il semaforo ‘down’ avviene in un thread (produttore) e semaforo ‘up’ (per lo stesso semaforo) avviene in un altro thread (consumer) es .: Nel problema produttore-consumatore, il produttore vuole dormire fino a quando almeno uno spazio del buffer è vuoto – solo il thread del consumatore può dire quando uno spazio del buffer è vuoto.

Mutex: usa un mutex quando tu (thread) vuoi eseguire codice che non dovrebbe essere eseguito da nessun altro thread allo stesso tempo. Mutex ‘down’ si verifica in un thread e il mutex ‘up’ deve avvenire nello stesso thread in seguito. Ad esempio: se si elimina un nodo da un elenco collegato globale, non si desidera che un altro thread muck intorno con i puntatori mentre si elimina il nodo. Quando si acquisisce un mutex e si sta occupando dell’eliminazione di un nodo, se un altro thread tenta di acquisire lo stesso mutex, verrà messo in sleep fino a quando non si rilascia il mutex.

Spinlock: usa uno spinlock quando vuoi veramente usare un mutex ma il thread non è autorizzato a dormire. Ad esempio: un gestore di interrupt nel kernel del sistema operativo non deve mai dormire. Se lo fa il sistema si bloccherà / si bloccherà. Se è necessario inserire un nodo nell’elenco globale condiviso condiviso dal gestore di interrupt, acquisire uno spinlock – inserire il nodo – rilasciare lo spinlock.

Un mutex è un object di mutua esclusione, simile a un semaforo ma che consente solo un armadietto alla volta e le cui restrizioni di proprietà possono essere più severe di un semaforo.

Può essere considerato equivalente a un normale semaforo di conteggio (con un conteggio di uno) e il requisito che possa essere rilasciato solo dallo stesso thread che lo ha bloccato (a) .

Un semaforo, d’altra parte, ha un conteggio arbitrario e può essere bloccato da quel numero di armadietti contemporaneamente. E potrebbe non essere necessario che venga rilasciato dallo stesso thread che lo ha richiesto (ma, in caso contrario, è necessario monitorare attentamente chi ne ha attualmente la responsabilità, proprio come la memoria allocata).

Quindi, se si dispone di un numero di istanze di una risorsa (ad esempio tre unità nastro), è ansible utilizzare un semaforo con un conteggio di 3. Si noti che questo non ti dice quale di quelle unità nastro hai, solo che hai un certo numero.

Inoltre con i semafori, è ansible che un singolo armadietto blocchi più istanze di una risorsa, ad esempio una copia da nastro a nastro. Se si dispone di una risorsa (ad esempio una posizione di memoria che non si desidera danneggiare), un mutex è più adatto.

Le operazioni equivalenti sono:

Counting semaphore Mutual exclusion semaphore -------------------------- -------------------------- Claim/decrease (P) Lock Release/increase (V) Unlock 

A parte: nel caso ti sia mai chiesto le bizzarre lettere usate per rivendicare e rilasciare semafori, è perché l’inventore era olandese. Probeer te verlagen significa provare e diminuire mentre verhogen significa aumentare.


(a) … o può essere pensato come qualcosa di totalmente distinto da un semaforo, che potrebbe essere più sicuro dato i loro usi quasi sempre diversi.

È molto importante capire che un mutex non è un semaforo con il conteggio 1!

Questo è il motivo per cui ci sono cose come i semafori binari (che sono davvero semafori con il numero 1).

La differenza tra un Mutex e un seminario binario è il principio di proprietà:

Un mutex viene acquisito da un’attività e, pertanto, deve essere rilasciato dalla stessa attività. Ciò rende ansible risolvere diversi problemi con i semafori binari (rilascio Accidentale, deadlock ricorsivo e inversione di priorità).

Avvertenza: ho scritto “rende ansible”, se e come questi problemi vengono corretti dipende dall’implementazione del sistema operativo.

Poiché il mutex deve essere rilasciato dallo stesso task, non è molto buono per la sincronizzazione delle attività. Ma se combinato con le variabili di condizione si ottengono blocchi di costruzione molto potenti per la costruzione di tutti i tipi di primitive ipc.

Quindi la mia raccomandazione è: se hai mutui implementati in modo pulito e variabili di condizione (come con i pthreads POSIX) usali.

Usa i semafori solo se si adattano esattamente al problema che stai cercando di risolvere, non provare a build altre primitive (ad esempio, i blocchi rw dei semafori, usa i mutex e le variabili di condizione per questi)

Vi sono molti mutex e semafori malintesi. La migliore spiegazione che ho trovato finora è in questo articolo in 3 parti:

Mutex vs. semafori – Parte 1: semafori

Mutex vs Semaphores – Part 2: The Mutex

Mutex vs. semafori – Parte 3 (parte finale): problemi di esclusione reciproca

Mentre la risposta di @opaxdiablo è totalmente corretta, vorrei sottolineare che lo scenario di utilizzo di entrambe le cose è molto diverso. Il mutex viene utilizzato per proteggere parti di codice da esecuzione simultanea, i semafori vengono utilizzati per un thread per segnalare un altro thread da eseguire.

 /* Task 1 */ pthread_mutex_lock(mutex_thing); // Safely use shared resource pthread_mutex_unlock(mutex_thing); /* Task 2 */ pthread_mutex_lock(mutex_thing); // Safely use shared resource pthread_mutex_lock(mutex_thing); 

Lo scenario del semaforo è diverso:

 /* Task 1 - Producer */ sema_post(&sem); // Send the signal /* Task 2 - Consumer */ sema_wait(&sem); // Wait for signal 

Vedi http://www.netrino.com/node/202 per ulteriori spiegazioni

Vedi “The Toilet Example” – http://pheatt.emporia.edu/courses/2010/cs557f10/hand07/Mutex%20vs_%20Semaphore.htm :

mutex:

È una chiave per un bagno Una persona può avere la chiave – occupare il bagno – al momento. Al termine, la persona dà (libera) la chiave alla prossima persona in coda.

Ufficialmente: “I mutex sono tipicamente usati per serializzare l’accesso a una sezione di codice di rientro che non può essere eseguita contemporaneamente da più di un thread.Un object mutex consente solo un thread in una sezione controllata, forzando altri thread che tentano di accedere a quella sezione per aspettare che il primo thread sia uscito da quella sezione. ” Rif: Symbian Developer Library

(Un mutex è in realtà un semaforo con valore 1.)

Semaforo:

È il numero di chiavi della toilette identiche gratuite. Esempio, diciamo che abbiamo quattro servizi igienici con serrature e chiavi identiche. Il conteggio dei semafori – il conteggio dei tasti – è impostato su 4 all’inizio (tutti e quattro i bagni sono gratuiti), quindi il valore del conteggio viene decrementato quando le persone arrivano. Se tutti i servizi igienici sono pieni, vale a dire. non ci sono chiavi libere, il conteggio del semaforo è 0. Ora, quando eq. una persona lascia la toilette, il semaforo viene aumentato a 1 (una chiave gratuita) e dato alla persona successiva in coda.

Ufficialmente: “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 finito di usare la risorsa (incrementando il semaforo). ” Rif: Symbian Developer Library

Cercando di non sembrare pazzesco, ma non posso aiutarmi.

La tua domanda dovrebbe essere qual è la differenza tra mutex e semafori? E per essere più precisi la domanda dovrebbe essere, ‘qual è la relazione tra mutex e semafori?’

(Avrei aggiunto quella domanda, ma sono sicuro al cento per cento che un moderatore troppo zelante lo chiuderebbe come duplicato senza capire la differenza tra differenza e relazione.)

Nella terminologia degli oggetti possiamo osservare che:

osservazione.1 Il semaforo contiene mutex

osservazione.2 Mutex non è un semaforo e il semaforo non è mutex.

Ci sono alcuni semafori che agiranno come se fossero mutex, chiamati semafori binari, ma non sono mutex.

C’è un ingrediente speciale chiamato Segnalazione (posix usa condition_variable per quel nome), richiesto per far diventare un semaforo del mutex. Pensala come una fonte di notifica. Se due o più thread sono abbonati alla stessa fonte di notifica, allora è ansible inviare loro un messaggio su ONE o su ALL, per il wakeup.

Potrebbero esserci uno o più contatori associati ai semafori, che sono protetti da mutex. Lo scenario più semplice per il semaforo, c’è un contatore singolo che può essere 0 o 1.

È qui che la confusione si riversa come la pioggia dei monsoni.

Un semaforo con un contatore che può essere 0 o 1 NON è mutex.

Mutex ha due stati (0,1) e una proprietà (attività). Il semaforo ha un mutex, alcuni contatori e una variabile di condizione.

Ora usa la tua immaginazione e ogni combinazione di utilizzo del contatore e quando segnalare può fare un tipo di semaforo.

  1. Contatore singolo con valore 0 o 1 e segnalazione quando il valore passa a 1 E quindi sblocca uno dei tipi che attendono il segnale == Semaforo binario

  2. Contatore singolo con valore da 0 a N e segnalazione quando il valore scende a meno di N, e blocca / attende quando i valori sono N == Conteggio semaforo

  3. Contatore singolo con valore da 0 a N e segnalazione quando il valore passa a N, e blocca / attende quando i valori sono inferiori a N == Semaforo della barriera (beh se non lo chiamano, allora dovrebbero).

Ora alla tua domanda, quando usare cosa. (OPPURE corretta domanda versione.3 quando usare il mutex e quando usare il binario-semaforo, poiché non c’è paragone con il semaforo non binario.) Usa mutex quando 1. vuoi un comportamento personalizzato, che non è fornito da binario semaforo, tali sono spin-lock o fast-lock o ricorsive-lock. Di solito è ansible personalizzare i mutex con gli attributi, ma personalizzare il semaforo non è altro che scrivere nuovi semafori. 2. vuoi una primitiva leggera o più veloce

Usa i semafori, quando ciò che vuoi è esattamente fornito da esso.

Se non capisci cosa viene fornito dalla tua implementazione di semaforo binario, quindi IMHO, usa il mutex.

E infine leggere un libro piuttosto che affidarsi solo a SO.

Penso che la domanda dovrebbe essere la differenza tra mutex e semaforo binario.

Mutex = È un meccanismo di blocco della proprietà, solo il thread che acquisisce il blocco può rilasciare il blocco.

binario Semaforo = È più un meccanismo di segnale, qualsiasi altro thread con priorità più alta se si vuole segnalare e prendere il blocco.

Mutex è proteggere la risorsa condivisa.
Il semaforo è di inviare i thread.

mutex:
Immagina che ci siano dei biglietti da vendere. Possiamo simulare un caso in cui molte persone comprano i biglietti allo stesso tempo: ogni persona è una discussione per acquistare i biglietti. Ovviamente abbiamo bisogno di usare il mutex per proteggere i ticket perché è la risorsa condivisa.

Semaforo:
Immagina di dover eseguire un calcolo come di seguito:

 c = a + b; 

Inoltre, abbiamo bisogno di una funzione geta() per calcolare a , una funzione getb() per calcolare b e una funzione getc() per eseguire il calcolo c = a + b .

Ovviamente, non possiamo fare c = a + b meno che geta() e getb() siano stati completati.
Se le tre funzioni sono tre thread, è necessario inviare i tre thread.

 int a, b, c; void geta() { a = calculatea(); semaphore_increase(); } void getb() { b = calculateb(); semaphore_increase(); } void getc() { semaphore_decrease(); semaphore_decrease(); c = a + b; } t1 = thread_create(geta); t2 = thread_create(getb); t3 = thread_create(getc); thread_join(t3); 

Con l’aiuto del semaforo, il codice sopra può essere sicuro che t3 non farà il suo lavoro fino a quando t1 e t2 avranno fatto il loro lavoro.

In una parola, semaforo consiste nel far eseguire i thread come un ordine logico mentre mutex è proteggere la risorsa condivisa.
Quindi NON sono la stessa cosa anche se alcune persone dicono sempre che il mutex è un semaforo speciale con il valore iniziale 1. Puoi dire anche questo, ma per favore nota che sono usati in diversi casi. Non sostituire l’uno con l’altro, anche se puoi farlo.

Come è stato sottolineato, un semaforo con un conteggio di uno è la stessa cosa di un semaforo ‘binario’ che è la stessa cosa di un mutex.

Le cose principali che ho visto semafori con un conteggio maggiore di quello utilizzato sono le situazioni produttore / consumatore in cui si ha una coda di una determinata dimensione fissa.

Allora hai due semafori. Il primo semaforo è inizialmente impostato per essere il numero di elementi nella coda e il secondo semaforo è impostato su 0. Il produttore esegue un’operazione P sul primo semaforo, aggiunge alla coda. e fa un’operazione V sul secondo. Il consumatore esegue un’operazione P sul secondo semaforo, rimuove dalla coda e quindi esegue un’operazione V sul primo.

In questo modo il produttore viene bloccato ogni volta che riempie la coda e il consumatore viene bloccato ogni volta che la coda è vuota.

Un mutex è un caso speciale di un semaforo. Un semaforo consente di inserire diversi thread nella sezione critica. Quando si crea un semaforo si definisce come possono essere consentiti i thread nella sezione critica. Ovviamente il tuo codice deve essere in grado di gestire diversi accessi a questa sezione critica.

Tutte le risposte di cui sopra sono di buona qualità, ma questa è solo per memorizzare. Il nome Mutex è derivato da Mutualmente esclusivo, quindi sei motivato a pensare a un mutex lock come esclusione reciproca tra due come in uno solo alla volta, e se io posseduto lo si può avere solo dopo averlo rilasciato. D’altra parte tale caso non esiste per il semaforo è proprio come un segnale di traffico (che significa anche la parola Semaforo).