- Un processo genera due processi figli P1 e P2
#include <stdio.h>
#include <unistd.h>
int main() {
pid_t p1 = fork();
if (p1 == 0) {
printf("Ciao sono il processo P1 : %d\n", getpid());
} else {
pid_t p2 = fork();
if (p2 == 0)
printf("Ciao sono il processo P2 : %d\n", getpid());
}
return 0;
}
È giusto ma possiamo migliorarlo, siccome il padre potrebbe finire prima e lasciare due zombies, quindi implementiamo l’attesa dei figlio prima che il padre finisca (basta aggiungere uno sleep).
#include <stdio.h>
#include <unistd.h>
int main() {
pid_t p1 = fork();
if (p1 == 0) {
printf("Ciao sono il processo P1 : %d | figlio di %d\n", getpid(),
getppid());
} else {
pid_t p2 = fork();
if (p2 == 0) {
sleep(2);
printf("Ciao sono il processo P2 : %d | figlio di %d\n", getpid(),
getppid());
} else {
wait(NULL); // attesa
wait(NULL); // attesa
printf("Ciao sono il processo padre : %d\n", getpid());
}
}
return 0;
}- Il figlio P1 esegue un ciclo indeterminato durante il quale genera casualmente numeri interi compresi tra 0 a 100. P1 comunica, ad ogni interazione, il numero al padre solo se esso è pari.
Abbiamo supporto un ciclo del figlio di 10 o 20 o 50 iterazioni :
#include <stdio.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
void p(const char *msg) { printf("[%d -> %d] %s", getppid(), getpid(), msg); }
int main() {
int fd[2];
pipe(fd);
pid_t p1 = fork();
if (p1 == 0) {
close(fd[0]);
p("Ciao sono il processo P1\n");
srand(time(NULL));
for (int i = 0; i < 10; i++) {
int random = rand() % 10;
if ((random % 2) == 0) {
p("");
printf("Number random : %d\n", random);
write(fd[1], &random, sizeof(int));
}
}
close(fd[1]); // questo chiude lato scrittura e permette al padre di finire
// il ciclo
} else {
close(fd[1]);
int rec;
while (read(fd[0], &rec, sizeof(int))) {
p("Received ");
printf("%d\n", rec);
}
close(fd[0]);
wait(NULL);
}
return 0;
}- il P2 fa la stessa cosa ma comunica al padre solo numeri dispari e il padre per ogni coppia di numeri che riceve dai figli fa la somma e la visualizza
Abbiamo introdotto una funzione work_p che fa il lavoro per non avere codice “duplicato” :
void work_p(int fd[2], char *name) {
close(fd[0]);
p("Ciao sono il processo ");
printf("%s\n", name);
srand(time(NULL) + getpid()); // seed diversi per processo
for (int i = 0; i < 10; i++) {
int random = rand() % 10;
if ((random % 2) != 0) {
if (!strcmp(name, "P2")) {
p("");
printf("Number random dispari : %d\n", random);
write(fd[1], &random, sizeof(int));
}
} else {
if (!strcmp(name, "P1")) {
p("");
printf("Number random pari : %d\n", random);
write(fd[1], &random, sizeof(int));
}
}
sleep(1);
}
close(fd[1]);
}
int main() {
int fd2[2];
int fd1[2];
pipe(fd1); // flusso P1 -> P
pid_t p1 = fork();
if (p1 == 0) {
work_p(fd1, "P1");
} else {
pipe(fd2); // flusso P2 -> P
pid_t p2 = fork();
if (p2 == 0) {
work_p(fd2, "P2");
} else {
close(fd1[1]);
close(fd2[1]);
int rec1;
int rec2;
while (1) {
// questa roba si può incorporare nella condizione del while
int r1 = read(fd1[0], &rec1, sizeof(int));
int r2 = read(fd2[0], &rec2, sizeof(int));
if (r1 <= 0 || r2 <= 0) {
// controllo if se uno dei read ha finito allora abbiamo finito perché
// non riusciamo a creare più coppie per la somma
break;
}
p("Received ");
printf("%d and %d | ", rec1, rec2);
printf("sum %d\n", rec1 + rec2);
}
close(fd2[0]);
close(fd1[0]);
wait(NULL);
wait(NULL);
}
}
return 0;
}
- quando la somma diventa allora il padre invia un segnale di terminazione a ogni figlio.
Abbiamo utilizzato > 10 :
int sum = rec1 + rec2;
p("Received ");
printf("%d and %d | ", rec1, rec2);
printf("sum %d\n", sum);
if (sum > 10) {
p("Sum is to high!....\n");
kill(p1, SIGTERM);
kill(p2, SIGTERM);
break;
}
