Newsgroup: it.comp.lang.c++
Titolo: Crosspost - Curiosità su mutex e semafori

Stavo pensando ai semafori ed alle differenze rispetto ad i mutex. Se
ho un mutex sono certo che un solo thread per volta sarà in sezione
critica, mentre se ci provano gli altri si bloccano.
Così se ho tre processi A, B e C, può accadere che A tenti il lock del
mutex e riesca ad entrare in sezione critica. Al tentativo di B e C di
entrare in sezione critica, i due thread resteranno sospesi/bloccati/
quellochesia fin quando A non uscirà dalla sezione critica eseguendo
una unlock() sul mutex, risvegliando automaticamente uno dei due
thread B e C.
Fin qui ci sono?
Quindi se volessi potrei implementare, a scopo più o meno didattico,
una classe semaforo partendo dai mutex?
O mi sto perdendo qualcosa?

 Marco
down() e up() ed ovviamente lo potrei inizializzare con un valore che
non sia solo 1 o 0 ma anche 7 per esempio...

 Marco
Ma la mia domanda era rivolta più verso la possibilità di utilizzare
un mutex per realizzare un semaforo piuttosto che dovermi affidare a
ciò che l'OS mi mette a disposizione perchè magari più atomici :D

 O mi sto perdendo qualcosa?
No, ti sei perso del tutto.

> No, ti sei perso del tutto.
Cioè se ho tre thread ed uno esegue un lock sul mutex, gli altri due
thread non si bloccano se eseguono anch'essi un lock sullo stesso
mutex? Cosa mi sono perso del tutto?
A parte che i mutex "possono" essere dei semafori binari, ma non sono
dei semafori.

 una classe semaforo partendo dai mutex?
Certamente. Mutex, semafori, monitor, eccetera sono tutti equivalenti,
nel
senso che ognuno di questi costrutti puo' essere costruito usando
uno qualsiasi degli altri. Naturalmente nel tuo caso ti serviranno
piu'
di un mutex, almeno uno per bloccare i thread e uno per rendere
l'accesso
al contatore del semaforo una critical section.
ciao
Giacomo

 al contatore del semaforo una critical section.
Infatti avevo pensato a qualcosa di simile:
mutex_t m, lck;
int sem_val;
void down()
{
  lock(m); /* sezione critica */
  sem_val--;
  /* se il semaforo non da bloccare, rendo non-bloccante l'ultimo lock
() */
  if (sem_val >= 0) unlock(lck);
  unlock(m); /* fine sezione critica */
  lock(lck);
}
void up()
{
  lock(m); /* sezione critica */
  sem_val++;
  if (sem_val >= 0) unlock(lck);
  unlock(m) /* fine sezione critica */
}
Questo a grosse linee, ma in generale dovrebbe andare?
Il mio unico dubbio è nella chiamata up(), quando dentro la sezione
critica eseguo la unlock del mutex che blocca i threads che sono
rimasti bloccati nella chiamata alla down(). Ma non dovrebbero esserci
problemi a risvegliarli nella sezione critica, vero? Tanto è alla fine
ed il valore di incremento è stato eseguito. O sbaglio?

 dei semafori.
Edsger Dijkstra inventò i semafori per il sistema operativo
THE e li usò per sincronizzare i processi concorrenti. Una 
particolare tipo di semaforo è il mutex, cioè un semaforo 
che può assumere solo i valori 0 e 1.
In seguito i semafori evidenziarono dei problemi quali la 
facilità di commettere errori di programmazione o di 
provocare un deadlock per cui oggi si tende ad evitare 
del tutto i semafori usando altri costrutti più sofisticati
a meno di essere costretti ad usarli, cioè se il linguaggio
di programmazione non ha altre possibilità per 
sincronizzare thread o processi.
Similmente il mutex essendo un particolare tipo di 
semaforo, attualmente si preferisce implementarlo
con un monitor. 

 ed il valore di incremento è stato eseguito. O sbaglio?
No, e' corretto. I processi che risvegli non sono bloccati dentro una
sezione critica, ma fuori (ne sono usciti con unlock(m)) quindi niente
rischio deadlock.
ciao
Giacomo

 Giacomo
ciao
Antonello