I semafori POSIX sono semafori contatori che permettono di gestire la sincronizzazione dei thread POSIX.
Esistono altri meccanismi che, per mancanza di tempo, menzionano solamente:
sem_t sem_name
int sem_init(sem_t *sem, int pshared, unsigned int value)
sem
al valore value
. la variabile pshared
indica se il semaforo è condiviso tra thread (0) o processi (≠0);int sem_wait(sem_t *sem)
int sem_post(sem_t *sem
)int sem_getvalue(sem_t *sem, int *val)
val
;sem_destroy(sem_t *sem)
NOTA: su MacOS si devono usare i semafori con nome (vedere le dispense per maggiori dettagli)
Riprendiamo l’ultimo esercizio della volta scorsa: Creare 2 thread che aggiornano ripetutamente (in un ciclo for) una variabile condivisa count per un numero elevato di volte (ad esempio 1000000). Stampare il valore finale per osservare eventuali incrementi perduti…
for (j=0;j<MAX;j++) {
count++
}
(Seguiva una nota sulle ottimizzazioni del compilatore. Vedere le dispense della volta scorsa per maggiori dettagli)
Aggiungere un semaforo mutex per risolvere le interferenze. Notare l’esecuzione corretta al prezzo di una più bassa performance.
Realizzare la sincronizzazione tra 2 thread vista a lezione in cui T2
, prima di eseguire la porzione di codice < D >
deve attendere che T1
abbia eseguito il codice < A >
.
void * T1(void * j) {
sleep(3);
printf("Eseguito < A >\n");
sleep(3);
printf("Eseguito < B >\n");
}
void * T2(void * j) {
printf("Eseguito < C >\n");
printf("Eseguito < D >\n");
}
NOTA: non pubblico la soluzione di questo esercizio, provate da soli e mandate le vostre idee, commenti, tentativi, etc. su slack in modo che possiamo discuterne assieme!
-1
) e testare se si sta leggendo una cella vuota o scrivendo in una piena. Il consumatore deve scrivere nella cella il valore speciale, dopo che ha letto. Il test dovrebbe segnalare problemi di sincronizzazione nel caso non si utilizzino appropriatamente i semafori;>
) su un file.