/* Numero di giocatori nel sistema */
/* Numero di valori da estrarre */
/* Numero di valori in una cartella */
/* File name utilizzato per comunicare */
#define FILENAME "giocata"
/* Scrive un messaggio di errore e poi termina */
void errquit(char* message)
/* Genera un numero casuale fra 0 e max-1 */
/* True se questo processo e' un child */
/* True se il parent ha spedito una nuova giocata */
/* Numero di risposte dai child */
static int rispostemancanti;
void doparent(int* giocatori)
/* Cartella di numeri estratti, mantenuta come array di booleani */
/* Numero di valori ancora da estrarre */
/* File descriptor per il file condiviso*/
sigset_t newmask, oldmask, zeromask;
/* Contatori, variabili di appoggio */
/* Inizializza struttura dati */
for (i=0; i < MAXNUM; i++)
/* Apre il file con le giocate in lettura */
fd = open(FILENAME, O_WRONLY);
/* Inizializza signal handling */
signal(SIGUSR1, sig_usr1);
sigaddset(&newmask, SIGUSR1);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
while (!tombola && daestrarre > 0) {
/* Estrai un numero che non e' gia' stato estratto */
printf("Parent: prima dell'estrazione\n", valore);
valore = casuale(MAXNUM);
} while (estratti[valore]);
/* Scrive il valore estratto */
if (lseek(fd, SEEK_SET, 0) < 0)
errquit("PARENT: SEEK error");
if (write(fd, &valore, sizeof(int)) < 0)
errquit("PARENT: WRITE error");
/* Sveglia i giocatori */
for (i=0; i < NGIOCATORI; i++)
kill(giocatori[i], SIGUSR1);
/* Aspetta le risposte */
rispostemancanti = NGIOCATORI;
while (rispostemancanti > 0)
printf("Parent: Ricevute tutte le risposte\n");
printf("Parent: Tombola!\n");
printf("Parent: Nessuno ha vinto\n");
/* Scrive -1 per concludere la partita */
if (lseek(fd, SEEK_SET, 0) < 0)
errquit("PARENT: SEEK error");
if (write(fd, &valore, sizeof(int))<0)
errquit("PARENT: WRITE error");
/* sveglia tutti i giocatori */
/* attende la terminazione dei figli */
void sig_usr1_child(int signo)
/* Cartella di numeri, mantenuta come array di booleani */
/* Numeri mancanti alla tombola */
/* Maschere per gestione segnali */
sigset_t newmask, oldmask, zeromask;
/* File descriptor per il file condiviso*/
/* Contatori, variabili di appoggio */
/* Genera cartella casuale */
for (i=0; i < MAXNUM; i++)
while (i < DIMCARTELLA) {
valore = casuale(MAXNUM);
/* Apre il file con le giocate in lettura */
fd = open(FILENAME, O_RDONLY);
/* Inizializza signal handling */
signal(SIGUSR1, sig_usr1_child);
sigaddset(&newmask, SIGUSR1);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
/* Aspetto una nuova giocata */
if (lseek(fd, SEEK_SET, 0) < 0)
errquit("CHILD: SEEK error");
if (read(fd, &valore, sizeof(int))<0)
errquit("CHILD: READ error");
/* Se il valore e' negativo, qualcuno ha fatto tombola */
printf("Child[%d]: fine partita\n",getpid());
printf("Child[%d]: e' stato estratto %d\n",getpid(), valore);
printf("Child[%d]: ok!, mancano %d\n",getpid(), mancanti);
printf("Child[%d]: tombola\n",getpid());
/* Ho fatto tombola; spedisco un segnale SIGUSR2 al parent */
kill(getppid(), SIGUSR2);
/* Spedisco un segnale SIGUSR1 al parent per confermare la lettura */
kill(getppid(), SIGUSR1);
int main(int argc, char* argv[])
/* Process id ottenuto da fork */
/* Process id dei giocatori */
int giocatori[NGIOCATORI];
/* Faccio il fork di NGIOCATORI figli */
for (i=0; i < NGIOCATORI; i++) {
/* Scelgo cosa fare, a seconda che sia padre e/o figlio */