SPIEGAZIONE DETTAGLIATA DI sem_wait() E sem_post() ================================================ Un SEMAFORO è un CONTATORE che controlla l'accesso alle risorse condivise. OPERAZIONI BASE: ================ 1. sem_wait(&semaforo) → ASPETTA/DECREMENTA - Decrementa il contatore di 1 - Se il contatore è 0, il thread Si BLOCCA finché qualcuno non fa sem_post - Se il contatore > 0, il thread continua subito 2. sem_post(&semaforo) → SVEGLIA/INCREMENTA - Incrementa il contatore di 1 - Se c'è un thread bloccato, lo SVEGLIA ESEMPIO PRATICO CON gen.c: =========================== INIZIALIZZAZIONE: sem_gen = 0 sem_cubo = 0 sem_quadro = 0 CICLO 1: -------- GENERATORE fa: numero = 50 sem_post(&sem_cubo) → sem_cubo diventa 1 ✓ sem_post(&sem_quadro) → sem_quadro diventa 1 ✓ sem_wait(&sem_gen) → sem_gen è 0, GENERATORE SI BLOCCA! ⏸️ CUBO (che era bloccato) si sblocca: sem_wait(&sem_cubo) → sem_cubo diventa 0, CONTINUA ✓ calcola 50^3 = 125000 sem_post(&sem_gen) → sem_gen diventa 1 ✓ QUADRATO (che era bloccato) si sblocca: sem_wait(&sem_quadro) → sem_quadro diventa 0, CONTINUA ✓ calcola 50^2 = 2500 sem_post(&sem_gen) → sem_gen diventa 2 ✓ GENERATORE si sblocca! (sem_gen > 0) sem_wait(&sem_gen) → sem_gen diventa 1, CONTINUA ✓ VISUALIZZAZIONE TEMPORALE: ========================== TEMPO │ GENERATORE │ CUBO │ QUADRATO ─────┼───────────────┼───────────────┼────────────── t0 │ numero = 50 │ [BLOCCATO] │ [BLOCCATO] │ post(cubo) │ │ │ post(quadro) │ SVEGLIATO ✓ │ SVEGLIATO ✓ │ wait(gen) │ │ │ [BLOCCATO]✋ │ │ ─────┼───────────────┼───────────────┼────────────── t1 │ │ cubo = 125000 │ quadro = 2500 │ │ post(gen) │ post(gen) │ │ │ SVEGLIATO ✓ ─────┼───────────────┼───────────────┼────────────── t2 │ numero = 75 │ [BLOCCATO] │ [BLOCCATO] │ post(cubo) │ │ │ ... │ │ │ │ │ CONCETTI CHIAVE: ================ 1. sem_wait() BLOCCA il thread se il contatore è 0 → Usato dal CONSUMATORE per aspettare che il PRODUTTORE generi 2. sem_post() SVEGLIA un thread bloccato → Usato dal PRODUTTORE per dirgli "è pronto!" 3. I semafori inizializzati a 0 garantiscono che: - I consumer aspettano fino a quando il producer non produce - Il producer aspetta che i consumer finiscano 4. Il "bacchetta magica" è il CONTATORE: - Se è 0 → niente disponibile → sem_wait() BLOCCA - Se è > 0 → qualcosa disponibile → sem_wait() continua ANALOGIA DEL SEMAFORO: ====================== Immagina una CASSA CON BIGLIETTI: sem_init(&semaforo, 0, 0) → La cassa è VUOTA (0 biglietti) Quando arriva il PRODUTTORE: sem_post() → Mette un biglietto nella cassa Quando arriva un CONSUMER: sem_wait() → Prende un biglietto (se c'è) → Se la cassa è vuota, aspetta fuori Se arrivano 2 consumer: - Primo fa sem_wait() → prende il biglietto, continua - Secondo fa sem_wait() → la cassa è vuota, SI BLOCCA - Quando produttore fa sem_post() → aggiunge biglietto - Secondo consumer si sblocca → prende il biglietto Semplice no? 😊