Bonjour,
Je ne souhaite ajouter qu'un petit exemple, apaachee t'as vraiment donné une excellente explication.
Soit le code suivant :
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void)
{
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[80];
pipe(fd);
if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}
if(childpid == 0)
{
/* Child process closes up input side of pipe */
close(fd[0]);
/* Send "string" through the output side of pipe */
write(fd[1], string, (strlen(string)+1));
exit(0);
}
else
{
/* Parent process closes up output side of pipe */
close(fd[1]);
/* Read in a string from the pipe */
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
}
return(0);
}
Il s'agit d'une simple transmission d'un "Hello World" entre deux processus.
Allez, détaillons un peu le tout.
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[80];
Déclarations des variables comprenant donc:
le message à transmettre (string)
un buffer de lecture (readbuffer)
l'identifiant du processus fils (childpid)
un tableau d'entiers (fd) permettant de définir les descripteurs de fichiers utilisé par le "pipe"
un entier qui sera utile plus tard (nbytes).
Jusque là, rien de spécial pour du développement en C...
pipe(fd);
Cette méthode système permet de créer 2 descripteurs de fichiers pour permettre la création d'un tuyau de communication entre 2 processus.
SYSTEM CALL: pipe();
PROTOTYPE: int pipe( int fd[2] );
RETURNS: 0 on success
-1 on error: errno = EMFILE (no free descriptors)
EMFILE (system file table is full)
EFAULT (fd array is not valid)
NOTES: fd[0] is set up for reading, fd[1] is set up for writing
Contrairement à ce qu'a dit apaachee,
La sortie (lecture) se fait dans fd[0]
L'entrée (écriture) se fait dans fd[1]
Maintenant, la création d'un processus fils :
if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}
Ici, nous créons un "fork" du programme principal, la condition et le reste c'est juste pour un contrôle d'erreurs et éviter les mauvaises surprises.
if(childpid == 0)
{
/* Child process closes up input side of pipe */
close(fd[0]);
/* Send "string" through the output side of pipe */
write(fd[1], string, (strlen(string)+1));
exit(0);
}
Là nous traitons l'exécution du fils, dans cet exemple celui-ci ferme le descripteur de fichier fd[0] car il ne l'utilisera pas.
Ensuite, il va écrire (write(...)) dans le descripteur de fichier fd[1] la chaine définie plus haut.
else
{
/* Parent process closes up output side of pipe */
close(fd[1]);
/* Read in a string from the pipe */
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
}
Nous retournons à présent dans le programme principal (le papa) pour lire le message du fils, il commence donc par fermer le descripteur de fichier fd[1] car il ne l'utilisera pas.
Ensuite, il va lire le message reçu dans le tuyau (read(...)) par l'intermédiaire du descripteur de fichier fd[0].
La fonction "read" retourne le nombre d'octets lus, cela peut s'avérer plus qu'utilise dans certains cas.
Voila, avec ça tu sais tout