/* versione con segnali inviati da padre ai figli */ #include #include #include #include #include #include #include #include typedef int pipe_t[2]; typedef struct{ int id; /* indice figlio (campo c1 del testo) */ int num; /* numero caratteri (campo c2 del testo) */ } s_occ; /* Variabili globali */ char linea[256]; /* buffer linea: si puo' supporre che una linea sia lunga al massimo 255 caratteri (256 con il terminatore di linea) */ int stampate; /* numero linee stampate (come variabile globale e' automaticamente inizializzata a 0 */ s_occ cur; /* struttura usata dal figlio corrente */ /* funzioni per trattare i segnali SIGUSR1 e SIUSR2: la prima fara' la scrittura su stdout, mentre la seconda non fara' nulla */ void scrivi(int sig) { /* se il padre ha detto che devo scrivere allora si scrive la linea su standard output usando le write su 1 */ write(1,linea,cur.num); stampate++; } void salta(int sig) { /* non si deve fare nulla */ } int main (int argc, char **argv) { int N; /* numero di file */ int H; /* numero positivo */ int *pid; /* array di pid: N.B. In questo caso serve un array di pid per fare in modo che il padre invii i segnali ai figli! */ pipe_t *pipes; /* array di pipe usate a pipeline da primo figlio, a secondo figlio .... ultimo figlio e poi a padre: ogni processo legge dalla pipe i-1 e scrive sulla pipe i */ int i,j; /* contatori */ int fd; /* file descriptor */ int pidFiglio, status, ritorno; /* per valore di ritorno figli */ s_occ pip; /* struttura usata dal figlio e per la pipe */ if (argc < 3) /* il testo non specifica nessun vincolo, ma per avere senso l'esecuzione ci deve essere almeno un file e il numero di linee */ { printf("Errore numero di parametri, dato che argc=%d\n", argc); exit(1); } H = atoi(argv[argc-1]); printf("Numero di linee %d\n", H); if (H <= 0 || H >= 255) /* il numero deve essere strettamente positivo e strettamente minore di 255 */ { printf("Errore numero linee\n"); exit(2); } N = argc-2; printf("DEBUG-Numero di processi da creare %d\n", N); /* allocazione pipe */ if ((pipes=(pipe_t *)malloc(N*sizeof(pipe_t))) == NULL) { printf("Errore allocazione pipe\n"); exit(3); } /* allocazione pid */ if ((pid=(int *)malloc(N*sizeof(int))) == NULL) { printf("Errore allocazione pid\n"); exit(4); } /* creazione pipe */ for (i=0;i0) { /* aggiorno conteggio lunghezza linea */ cur.num++; if (linea[cur.num-1]=='\n') { if (i!=0) /* se non sono il primo figlio */ { /* lettura da pipe della struttura */ read(pipes[i-1][0],&pip,sizeof(s_occ)); if (cur.num < pip.num) { /* se la lunghezza calcolata e' minore di quella ricevuta, si deve mandare avanti quella ricevuta */ cur.id = pip.id; cur.num = pip.num; } } /* printf("valore i = %d\n", i); printf("valore cur.id = %d\n", cur.id); printf("valore cur.num = %d\n", cur.num); */ /* comunicazione lunghezza linea */ write(pipes[i][1],&cur,sizeof(s_occ)); /* aspetto segnale dal padre */ /* printf("prima di pause\n"); */ pause(); /* dopo l'arrivo del segnale azzero il conteggio linea precedente */ cur.num=0; /* e ripristino l'indice del processo */ cur.id = i; } } exit(stampate); /* torna il numero di linee scritte su standard output */ } } /* fine for */ /* codice del padre */ /* chiusura pipe: tutte meno l'ultima in lettura */ for(i=0;i> 8) & 0xFF); printf("Il figlio con pid=%d ha ritornato %d (se 255 problemi!)\n", pidFiglio, ritorno); } } exit(0); }