1. 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;
}

  1. 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;
}
  1. 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;
}
 
  1. 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;
        }