[semafori] Imbuto 2.0

Si devono sincronizzare un certo numero di thread pallina in modo che entrino in un imbuto solo a gruppi di una dimensione prefissata N e, dopo un certo tempo, escono dall’imbuto. Solo nel momento in cui sono usciti tutti, il gruppo successivo di N thread pallina può accedere.

ATTENZIONE: non è il thread principale a sbloccare i gruppi di thread pallina, ma sono le palline stesse che si sincronizzano autonomamente.

Il thread principale si limita a inizializzare i semafori, creare i thread pallina attendere la loro terminazione e eliminare i semafori, secondo il seguente schema. La dimensione dei gruppi N viene passata a inizializza_sem in modo da poter essere utilizzata, successivamente, per la sincronizzazione.

inizializza_sem(N); // inizializza i semafori e salva N

// Crea i thread pallina e attende la loro terminazione

distruggi_sem(); // distruggi i semafori

Lo schema del thread “pallina” è il seguente:

entra_imbuto(); // attende di entrare nell'imbuto

// entra nell'imbuto e percorri tutta la strada verso il fondo

esci_imbuto(); // esce dall'imbuto 

L’obiettivo della verifica è di implementare le 2 funzioni di sincronizzazione entra_imbuto e esci_imbuto tramite semafori (più le 2 funzioni inizializza_sem e distruggi_semper inizializzare e eliminare i semafori) in modo da realizzare il comportamento richiesto.

IMPORTANTE: la funzione esci_imbuto deve necessariamente contare il numero di palline che sono uscite dall’imbuto per poi sbloccare il gruppo successivo: questa sincronizzazione non è realizzabile utilizzando solamente wait e post sui semafori. Utilizzare, a tale scopo, una variabile globale proteggendo opportunamente la sezione critica. Non ci sono problemi a fare delle post su altri semafori dentro una sezione critica perché le post non sono mai bloccanti.

Le funzioni da implementare sono nel file soluzione.c che va compilato assieme a imbuto2.c (scarica lo zip). Compilare con gcc soluzione.c imbuto2.c -o imbuto2 -pthread.

Una volta che funziona, compilare con l’opzione -DSTRESSTEST che testa il programma con un numero elevato di thread e senza sleep (in modo da aumentare la probabilità di race condition). Per ripetere il test in automatico potete usare questo semplice script bash: while true; do ./imbuto2; done