tkt
This commit is contained in:
BIN
SCR3.1/TP5/Exo1/a.out
Executable file
BIN
SCR3.1/TP5/Exo1/a.out
Executable file
Binary file not shown.
183
SCR3.1/TP5/Exo1/pipe-ex.c
Normal file
183
SCR3.1/TP5/Exo1/pipe-ex.c
Normal file
@@ -0,0 +1,183 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define READ_END 0
|
||||
#define WRITE_END 1
|
||||
|
||||
// Fonction pour la gestion des erreurs
|
||||
void error_exit(const char *msg) {
|
||||
perror(msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Fonction du processus Pf2 (Écriture)
|
||||
void process_pf2(int pipefd[2]) {
|
||||
// Pf2 n'a besoin que de l'extrémité d'écriture du tube
|
||||
if (close(pipefd[READ_END]) == -1) {
|
||||
error_exit("Pf2: close(READ_END)");
|
||||
}
|
||||
|
||||
printf("Pf2 (PID: %d) démarré. Écrit toutes les 3 secondes.\n", getpid());
|
||||
|
||||
pid_t pid_to_write;
|
||||
|
||||
while (1) {
|
||||
pid_to_write = getpid();
|
||||
ssize_t bytes_written = write(pipefd[WRITE_END], &pid_to_write, sizeof(pid_t));
|
||||
|
||||
if (bytes_written == -1) {
|
||||
if (errno == EPIPE) {
|
||||
// Le tube a été fermé par le lecteur (Pf1f1)
|
||||
fprintf(stderr, "Pf2 (PID: %d): Erreur: Pipe fermé. Arrêt de l'écriture.\n", getpid());
|
||||
break;
|
||||
}
|
||||
error_exit("Pf2: write");
|
||||
}
|
||||
|
||||
printf("Pf2 (PID: %d) écrit: %d (taille: %zd octets)\n", getpid(), pid_to_write, bytes_written);
|
||||
|
||||
// Attendre 3 secondes
|
||||
sleep(3);
|
||||
}
|
||||
|
||||
// Fermer l'extrémité d'écriture avant de terminer
|
||||
if (close(pipefd[WRITE_END]) == -1) {
|
||||
error_exit("Pf2: close(WRITE_END) final");
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
// Fonction du processus Pf1f1 (Lecture)
|
||||
void process_pf1f1(int pipefd[2]) {
|
||||
// Pf1f1 n'a besoin que de l'extrémité de lecture du tube
|
||||
if (close(pipefd[WRITE_END]) == -1) {
|
||||
error_exit("Pf1f1: close(WRITE_END)");
|
||||
}
|
||||
|
||||
printf("Pf1f1 (PID: %d) démarré. Lit toutes les 1 seconde.\n", getpid());
|
||||
|
||||
pid_t received_pid;
|
||||
ssize_t bytes_read;
|
||||
|
||||
while (1) {
|
||||
bytes_read = read(pipefd[READ_END], &received_pid, sizeof(pid_t));
|
||||
|
||||
if (bytes_read == -1) {
|
||||
error_exit("Pf1f1: read");
|
||||
} else if (bytes_read == 0) {
|
||||
// Fin de fichier (l'écrivain Pf2 a fermé son extrémité)
|
||||
printf("Pf1f1 (PID: %d): Fin du tube détectée. Arrêt de la lecture.\n", getpid());
|
||||
break;
|
||||
} else if (bytes_read != sizeof(pid_t)) {
|
||||
// Lecture partielle inattendue
|
||||
fprintf(stderr, "Pf1f1 (PID: %d): Avertissement: Lecture partielle (%zd octets au lieu de %zu)\n",
|
||||
getpid(), bytes_read, sizeof(pid_t));
|
||||
} else {
|
||||
// Lecture réussie
|
||||
printf("Pf1f1 (PID: %d) lit: %d (taille: %zd octets)\n", getpid(), received_pid, bytes_read);
|
||||
}
|
||||
|
||||
// Attendre 1 seconde
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
// Fermer l'extrémité de lecture avant de terminer
|
||||
if (close(pipefd[READ_END]) == -1) {
|
||||
error_exit("Pf1f1: close(READ_END) final");
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int pipefd[2];
|
||||
pid_t pid_pf2, pid_pf1, pid_pf1f1;
|
||||
|
||||
printf("Processus P (PID: %d) démarré.\n", getpid());
|
||||
|
||||
// 1. Créer le tube entre Pf2 et Pf1f1
|
||||
if (pipe(pipefd) == -1) {
|
||||
error_exit("pipe");
|
||||
}
|
||||
printf("Tube créé: descripteur de lecture=%d, descripteur d'écriture=%d\n",
|
||||
pipefd[READ_END], pipefd[WRITE_END]);
|
||||
|
||||
// 2. Créer Pf2
|
||||
pid_pf2 = fork();
|
||||
if (pid_pf2 == -1) {
|
||||
error_exit("fork Pf2");
|
||||
}
|
||||
|
||||
if (pid_pf2 == 0) {
|
||||
// Code de Pf2
|
||||
process_pf2(pipefd);
|
||||
}
|
||||
|
||||
// Processus P (continue)
|
||||
// 3. Créer Pf1
|
||||
pid_pf1 = fork();
|
||||
if (pid_pf1 == -1) {
|
||||
error_exit("fork Pf1");
|
||||
}
|
||||
|
||||
if (pid_pf1 == 0) {
|
||||
// Code de Pf1
|
||||
printf("Pf1 (PID: %d) démarré. Création de Pf1f1.\n", getpid());
|
||||
|
||||
// 4. Créer Pf1f1 (fils de Pf1)
|
||||
pid_pf1f1 = fork();
|
||||
if (pid_pf1f1 == -1) {
|
||||
error_exit("fork Pf1f1");
|
||||
}
|
||||
|
||||
if (pid_pf1f1 == 0) {
|
||||
// Code de Pf1f1
|
||||
process_pf1f1(pipefd);
|
||||
} else {
|
||||
// Pf1 attend la terminaison de Pf1f1
|
||||
printf("Pf1 (PID: %d) attend Pf1f1 (PID: %d).\n", getpid(), pid_pf1f1);
|
||||
|
||||
// Pf1 ne lit ni n'écrit dans le tube, donc il doit fermer les deux descripteurs hérités
|
||||
if (close(pipefd[READ_END]) == -1) {
|
||||
error_exit("Pf1: close(READ_END)");
|
||||
}
|
||||
if (close(pipefd[WRITE_END]) == -1) {
|
||||
error_exit("Pf1: close(WRITE_END)");
|
||||
}
|
||||
|
||||
if (waitpid(pid_pf1f1, NULL, 0) == -1) {
|
||||
error_exit("waitpid Pf1f1");
|
||||
}
|
||||
printf("Pf1 (PID: %d): Pf1f1 terminé.\n", getpid());
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
// Processus P (attente des enfants)
|
||||
printf("P (PID: %d) attend Pf2 (PID: %d) et Pf1 (PID: %d).\n", getpid(), pid_pf2, pid_pf1);
|
||||
|
||||
// Le processus P ne communique pas via le tube, il doit donc fermer les descripteurs hérités
|
||||
if (close(pipefd[READ_END]) == -1) {
|
||||
error_exit("P: close(READ_END)");
|
||||
}
|
||||
if (close(pipefd[WRITE_END]) == -1) {
|
||||
error_exit("P: close(WRITE_END)");
|
||||
}
|
||||
|
||||
// Attendre la terminaison des deux processus enfants directs (Pf2 et Pf1)
|
||||
if (waitpid(pid_pf2, NULL, 0) == -1) {
|
||||
error_exit("waitpid Pf2");
|
||||
}
|
||||
printf("P (PID: %d): Pf2 terminé.\n", getpid());
|
||||
|
||||
if (waitpid(pid_pf1, NULL, 0) == -1) {
|
||||
error_exit("waitpid Pf1");
|
||||
}
|
||||
printf("P (PID: %d): Pf1 terminé.\n", getpid());
|
||||
|
||||
printf("P (PID: %d): Tous les processus enfants sont terminés. Sortie.\n", getpid());
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user