Kazuhiro和宏
Résoud ce mini projet : Mini Projet : Communication inter processus (Tubes) L2: OS Utilisateur Création d'un tube La création d'un tube est réalisée grâce à la primitive pipe()qui utilise deux descripteurs de fichier (un tableau de deux entiers). #include int pipe (int p[2]); Un tube correspond donc à la description de 2descripteurs de fichiers, l'un permettant d'écrire dans le tube (p[1]), l'autre permettant d'y lire (p[0]). Utilisation d'un tube On utilise alors les opérations classiques de lecture et d'écriture (primitives read() et write()). Si un processus père crée un tube et qu'il fait ensuite un appel à fork() pour créer un processus fils, comme le fils est l'exacte copie du père, il héritera lui aussi du tube. Il disposera donc des mêmes descripteurs en lecture/écriture aux extrémités du tube. Pour que deux processus puissent communiquer des données par un tube, il faut être le descendant d'un même père (ou ancêtre commun) qui crée le tube. Ce dernier peut lui-même être l'un des processus communiquant. Ennoncé : Ecrire un programme tube_com_processl.exe qui crée un tube et y écrit 10 caractères ("0123456789" en une seule écriture). Le programme appelle ensuite une fonction void lecture(int fd) qui lit le contenu du tube caractère par caractère jusqu'à la fin de fichier. Pour faire l'affichage des caractères lus dans lecture, vous utiliserez aussi la fonction write sur le descripteur de fichier de la sortie standard. Question 1: un seul processus sera mis en jeu et sera à la fois écrivain et lecteur du tube. Question 2: Ecrire un programme tube_com_process2.exe. Pour cette seconde version, le processus père sera l'écrivain dans le tubeet le processus fils fera appel à la fonction lecture mise en place précédemment.

Voici un exemple de solution en utilisant les primitives de gestion de tubes (pipe) et de création de processus (fork) en C :

Pour le premier programme (tube_com_process1.exe) :

#include <unistd.h> #include <stdio.h> int main(void) { // Création du tube int tube[2]; if (pipe(tube) == -1) { perror("Erreur lors de la création du tube"); return 1; } // Écriture des 10 caractères dans le tube const char *chaine = "0123456789"; if (write(tube[1], chaine, 10) == -1) { perror("Erreur lors de l'écriture dans le tube"); return 1; } // Fermeture de l'extrémité d'écriture du tube if (close(tube[1]) == -1) { perror("Erreur lors de la fermeture de l'extrémité d'écriture du tube"); return 1; } // Lecture du contenu du tube caractère par caractère char c; while (read(tube[0], &c, 1) > 0) { // Affichage du caractère lu sur la sortie standard if (write(1, &c, 1) == -1) { perror("Erreur lors de l'affichage du caractère lu"); return 1; } } // Fermeture de l'extrémité de lecture du tube if (close(tube[0]) == -1) { perror("Erreur lors de la fermeture de l'extrémité de lecture du tube"); return 1; } return 0; }

Pour le second programme (tube_com_process2.exe) :

#include <unistd.h> #include <stdio.h> // Fonction de lecture du contenu du tube void lecture(int fd) { char c; while (read(fd, &c, 1) > 0) { // Affichage du caractère lu sur la sortie standard if (write(1, &c, 1) == -1) { perror("Erreur lors de l'affichage du caractère lu"); return; } } } int main(void) { // Création du tube int tube[2]; if (pipe(tube) == -1) { perror("Erreur lors de la création du tube"); return 1; } // Création du processus fils pid_t pid = fork(); if (pid == -1) { perror("Erreur lors de la création du processus fils"); return 1; } // Code exécuté par
Kazuhiro和宏
explique moi ce code en détails

Dans ces deux programmes, nous utilisons les primitives de gestion de tubes (pipe) et de création de processus (fork) de la bibliothèque standard Unix (unistd.h).

La primitive pipe() permet de créer un tube (un pipe en anglais) entre deux processus, qui peut être utilisé pour la communication entre ces deux processus. Elle prend en paramètre un tableau de deux entiers (int p[2]) et retourne 0 en cas de succès, ou -1 en cas d'erreur. Les deux entiers du tableau représentent les descripteurs de fichier associés au tube : p[0] correspond au descripteur de lecture et p[1] au descripteur d'écriture.

La primitive fork() permet de créer un nouveau processus à partir d'un processus existant (le processus père). Elle retourne le PID (identifiant de processus) du processus fils dans le processus père, 0 dans le processus fils, ou -1 en cas d'erreur. Le processus fils est une copie du processus père à tous les points de vue, sauf son PID et son PPID (identifiant de processus du père).

Dans le premier programme (tube_com_process1.exe), nous créons d'abord un tube avec la primitive pipe(). Nous écrivons ensuite les 10 caractères "0123456789" dans le tube avec la primitive write(). Nous fermons ensuite l'extrémité d'écriture du tube avec la primitive close(). Enfin, nous lisons le contenu du tube caractère par caractère avec la primitive read() et affichons chaque caractère sur la sortie standard avec la primitive write(). Nous fermons enfin l'extrémité de lecture du tube avec la primitive close().

Dans le second programme (tube_com_process2.exe), nous créons d'abord un tube avec la primitive pipe(). Nous créons ensuite un processus fils avec la primitive fork(). Dans le processus père, nous écrivons les 10 caractères "0123456789" dans le tube avec la primitive write() et fermons ensuite l'extrémité d'écriture du tube avec la primitive close(). Dans le processus fils, nous appelons la fonction de lecture du contenu du tube en lui passant le descripteur de lecture du tube en paramètre. Cette fonction lit le contenu du tube caractère par caractère et affiche chaque caractère sur la sortie standard avec la primitive write().

Je peux vous fournir plus de détails sur le fonctionnement de ces primitives si vous le souhaitez.

Generated With ChatGPT Export
ChatGPT Dec 15 Version. Free Research Preview. Our goal is to make AI systems more natural and safe to interact with. Your feedback will help us improve.