Devi usare un solo semaforo ed inizializzarlo a 0.
Poi le cose dovrebbero svolgersi più o meno così:
1. il primo thread (relativo alla prima porta di ingresso) impegna il semaforo attraverso una wait e lo decrementa di 1, adesso il semaforo ha valore negativo.
2. il secondo thread (relativo alla seconda porta di ingresso) tenta la wait sul semaforo, trova il valore negativo e quindi resta bloccato
3. il terzo thread (relativo alla terza porta di ingresso) tenta la wait sul semaforo, trova il valore negativo e quindi resta bloccato
4. il primo thread incrementa la variabile condivisa di uno (quella che riporta il numero dei partecipanti alla festa) e rilascia il semaforo (ovvero incrementa il suo valore di uno riportandolo a 0)
5. il secondo thread si sblocca grazie all'incremento del semaforo, blocca il semaforo, incrementa la variabile condivisa di 1 e sblocca il semaforo
... e così via
Il thread relativo alle uscite se ne frega del semaforo e può decrementare la variabile condivisa quando vuole.
Per implementare il semaforo puoi usare la libreria POSIX semaphore.h
Qui trovi diversi esempi
EDIT: in base all'esempio nel link la tua inizializzazione dovrebbe essere
sem_init(&mutex, 0, 1);