Le operazioni che ogni nodo intermedio della catena deve effettuare sono le seguenti:
C'è da notare che il descrittore di file pipeSUP ha un significato ben preciso: è il riferimento al canale di scrittura della pipe che collega un processo con il relativo padre. Quindi NON SI DEVE MODIFICARE il suo valore, mentre nextPIPE rappresenta il collegamento con il processo figlio. Durante la fase di creazione della catena, tutti i nodi intermedi passano da una fase in cui sono "figli" (ramo else dell'if fork) ad una in cui diventano "padri" (successiva fork dovuta al ciclo while): ed è in questa fase che il riferimento al canale di scrittura col processo padre viene "salvato" (assegnando a pipeSUP in valore di nextPIPE[1], che in quel punto specifico del codice rappresenta proprio il collegamento col padre). Al successivo ciclo, nextPIPE assumerà nuovi valori relativi alla nuova pipe, e quindi l'unico riferimento alla vecchia pipe rimane pipeSUP
Di seguito viene riportato il codice della soluzione proposta. E' possibile prelevare il file completo qui.
close(nextPIPE[1]);
printf("Processo %d: nodo", getpid());
if (pipeSUP == -1) printf(" iniziale ");
else printf(" intermedio ");
printf(": -> figlio = %d\n", figlio);
// read su pipeSX[0]
if (read(nextPIPE[0], &num, sizeof(int)) == -1) {
printf("Processo %d: errore durante la receive\n",getpid());
exit(1);
}
else
printf("Processo %d: ricevuto %d dal figlio.\n", getpid(), num);
num2 = my_random();
printf("Processo %d: nodo", getpid());
if (pipeSUP == -1) printf(" iniziale ");
else printf(" intermedio ");
printf(": valore generato = %d\n", num2);
num += num2;
if (pipeSUP != -1) // write su pipeSUP se != -1
if (write(pipeSUP, &num, sizeof(int))==-1) {
printf("Processo %d: errore durante la send\n", getpid());
exit(1);
}
else {
printf("Processo %d: send di %d al processo %d riuscita.\n", getpid(), num, getppid());
close(pipeSUP);
}
else // else sto alla radice e quindi stampo.
printf("Processo %d: il Risultato della somma è: %d\n", getpid(), num);
wait(&status);
break;