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
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.