#include #include #include #include #include #include #include #include #include #define NMAX 10 /* Globale perche' sia visibile in tutte le funzioni incluso il gestore del segnale */ int sigusr1_ricevuto; // Gestore del segnale SIGUSR1 void handler() { printf("Processo padre (%d) : ho ricevuto il segnale SIGUSR1\n",getpid()); sigusr1_ricevuto = 1 ; } int figlio(int i, int fd_letturapipe) { int contatore, numero ; printf("Processo figlio n. %d (%d) avviato \n",i, getpid()); contatore = 0 ; do { /* I figli competono per leggere il messaggio */ /* La read e' atomica : un solo processo alla volta riesce a leggere il numero mentre gli altri rimangono bloccati fino a quando riusciranno a leggere un numero */ read(fd_letturapipe, &numero, sizeof(int)); contatore += numero ; printf("Processo figlio (%d) : ricevuto %d - contatore %d\n",getpid(), numero, contatore); } while (contatore < 500); printf("Processo figlio (%d) : superata la soglia, invio SIGUSR1 al padre e termino\n",getpid()); kill(getppid(), SIGUSR1); return 0 ; } int main(int argc, char *argv[]) { int tabpid[NMAX],status,numero,numeri_inviati,n,i; int pipefd[2]; sigset_t sigmask; struct sigaction act; /* Controllo numero e valore degli argomenti */ if(argc<2 || (n=atoi(argv[1]))<=0 || n>=NMAX) { printf("ERRORE negli argomenti\n"); printf("Uso: programma \n"); printf("N deve essere maggiore di 0 e minore di %d\n",NMAX); exit(-1); } /* Processo padre */ /* Gestione segnali : i figli la ereditano */ act.sa_handler= handler ; sigemptyset(&act.sa_mask); act.sa_flags = 0 ; if(sigaction(SIGUSR1,&act,NULL)<0) { perror("errore sigaction: "); exit(2); } /* Blocco del segnale SIGUSR1 */ sigemptyset( &sigmask); sigaddset(&sigmask, SIGUSR1); sigprocmask(SIG_BLOCK, &sigmask, NULL); /* Creazione della pipe per la comunicazione dal padre ai figli (che erediteranno i descrittori) */ if(pipe(pipefd)<0) { perror("creazione pipe:"); exit(-3); } /* Creazione dei figli */ for(i=0;i