Ottenere la mutua esclusione
Ci sono diversi modi per realizzare la mutua esclusione:
- Disabilitare gli interrupt: non è una soluzione ottima, infatti non risolve il problema della mutua esclusione multi core, inoltre dare all’utente la possibilità di disabilitare gli interrupt può portare da abusi o bug da parte del programmatore
- Variabili di lock: funzionano bene solo se gestite a livello kernel, un programmatore potrebbe sbagliare
- Alternanza stretta: spiegazione
Un altro algoritmo utilizzato è quello di Peterson

Riusciamo a gestire N processi, abbiamo una variabile turn che prende il valore del processo scelto per entrare nella sezione critica
Istruzioni TSL e XCHG
DANGER
Mi sono distratto :)
Sleep e wakeup
è importante per un processo avere la possibilità di bloccarsi per risolvere il problema dell’inversione di priorità e questo lo fa usando le primitive:
- sleep: sospende l’esecuzione del chiamante, questo potrà tornare ad avere la CPU solo quando sarà risvegliato. Manderà il processo nello stato di “blocked”
- wakeup: sveglia il processo, facendolo tornare nello stato di “ready”
Consideriamo il problema del produttore-consumatore (ha commentato dicendo che si trova spesso al laboratorio) in pratica abbiamo:
- produttore
- consumatore
- buffer limitato Il produttore inserisce continuamente dati nel buffer, il consumatore consuma continuamente dati dal buffer, è importante ricordare che il consumatore non può consumare ciò che non esiste, di seguito la prima soluzione a questo problema:
# Definizione del Produttore (inserisce un item in loop)
function producer()
while (true) do
item = produce_item()
if (count == N) sleep()
insert_item(item)
count = count + 1
if (count == 1)
wakeup(consumer)
# Definizione del Consumatore (consuma un item in loop)
function consumer()
while (true) do
if (count == 0) sleep()
item = remove_item()
count = count - 1
if (count == N - 1)
wakeup(producer)
consume_item(item)
Questa soluzione ci porta lo stesso al deadlock, quindi nasce la soluzione dove viene implementato l’utilizzo di un flag di attesa chiamato wakeup
Semafori
Generalizzando il concetto di sleep e wakeup otteniamo un semaforo, un semaforo è composto da:
- una variabile S: che non può mai diventare negativa
- funzioni wait e signal: queste due operazioni incrementano/decrementano la variabile S. Se si prova ad effettuare il wait sul semaforo a 0 l’operazione diventa bloccante
Per il corretto funzionamento, bisogna fare in modo che down e up siano atomiche, pe
r evitare problemi con race condition sul semaforo.
Esistono diversi tipi di semaforo:
- Numerico: assume da 1-N, che si presa ai problemi di conteggio delle risorse, bloccando il thread quando questo esaurisce la risorsa
- Mutex: é un semaforo cui assume valori da , usato come flag per garantire la mutua esclusione
Di seguito la soluzione del problema produttore-consumatore
