Initiation aux tubes unix (pipe())

Contenu du snippet

On va dans la dernière partie simuler les tubes que crée le shell UNIX avec par ex
who | cut -c 1-5 | sort -u

Source / Exemple :


/* ---------------------------------------------------------------------------

  • les tubes Unix.
  • 1 : on crée un tube puis un processus fils. Le père envoie un message
  • au fils dans le tube et le fils répond.
  • Auteur(s) : adesport
  • Groupe TP :
  • Entrées : aucune
  • Sorties : traces à l'écran
  • --------------------------------------------------------------------------*/
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> /* Pour pid_t (fork, getpid, getppid) */ int main(void) { pid_t ident; int tube[2]; /* les deux descripteurs associés au tube */ char message[20]; /* Une chaîne pour stocker les messages lus
  • dans le tube */
if (pipe(tube) != 0) /* Création du tube */ { perror("pipe"); return EXIT_FAILURE; } ident = fork(); /* Création du fils */ switch (ident) { case -1 : perror("fork"); return EXIT_FAILURE; case 0 : /* Fils */ printf("Fils : je lis 31 caractères dans le tube\n"); read(tube[0], message, 31); printf("Fils : j'ai lu '%s'\n",message); printf("Fils : message1 du père lu, j'envoi message2\n"); write(tube[1], "message du fils pour le père 2", 31); break; default : /* Père */ write(tube[1], "message du père pour le fils 1", 31); wait(NULL); printf("Père : je lis 31 caractères dans le tube\n"); read(tube[0], message, 31); printf("Père : j'ai lu '%s'\n", message); } return EXIT_SUCCESS; } Trace: Fils : je lis 31 caractères dans le tube Fils : j'ai lu 'message du père pour le fils 1' Fils : message1 du père lu, j'envoi message2 Père : je lis 31 caractères dans le tube Père : j'ai lu 'message du fils pour le père 2' Problèmes : le père peut lire ce qu'il a envoyé avant que le fils ne le fasse --> on force l'attente avec wait(NUll), /* ---------------------------------------------------------------------------
  • les tubes Unix.
  • 1 : on crée un tube puis un processus fils. Le fils envoie un message
  • au père dans le tube le père répond.
  • Auteur(s) : adesport
  • Groupe TP :
  • Entrées : aucune
  • Sorties : traces à l'écran
  • --------------------------------------------------------------------------*/
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> /* Pour pid_t (fork, getpid, getppid) */ int main(void) { pid_t ident; int tube[2]; /* les deux descripteurs associés au tube */ char message[20]; /* Une chaîne pour stocker les messages lus
  • dans le tube */
if (pipe(tube) != 0) /* Création du tube */ { perror("pipe"); return EXIT_FAILURE; } ident = fork(); /* Création du fils */ switch (ident) { case -1: perror("fork"); return EXIT_FAILURE; case 0: /* Fils */ write(tube[1], "message du Fils pour le Père 1", 31); while (getppid() != 1) /* attend que le père meurt */ ; /*vide*/ printf("Fils : je lis 31 caractères dans le tube\n"); read(tube[0], message, 31); printf("Fils : j'ai lu '%s'\n", message); break; default: /* Père */ printf("Père : je lis 31 caractères dans le tube\n"); read(tube[0], message, 31); printf("Père : j'ai lu '%s'\n", message); printf("Père: message1 du Fils lu, j'envoi message2\n"); write(tube[1], "message du Père pour le Fils 2", 31); break; } return EXIT_SUCCESS; } TRACE : Père : je lis 31 caractères dans le tube Père : j'ai lu 'message du Fils pour le Père 1' Père: message1 du Fils lu, j'envoi message2 Fils : je lis 31 caractères dans le tube Fils : j'ai lu 'message du Père pour le Fils 2' La solution n'est pas la même que pour tout a l'heure car la mort du père précède la mort du fils (la primitive wait() ne peut donc pas s'appliquer). /* ---------------------------------------------------------------------------
  • Entrées : aucune
  • Sorties : traces à l'écran
  • --------------------------------------------------------------------------*/
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> /* Pour pid_t (fork, getpid, getppid) */ int main(void) { pid_t ident; int tube[2]; int tube2[2]; /* les deux descripteurs associés au tube */ char message[20]; /* Une chaîne pour stocker les messages lus
  • dans le tube */
if (pipe(tube) != 0) /* Création du tube 1*/ { perror("pipe"); return EXIT_FAILURE; } if (pipe(tube2) != 0) /* Création du tube 2*/ { perror("pipe"); return EXIT_FAILURE; } ident = fork(); /* Création du fils */ switch (ident) { case -1: perror("fork"); return EXIT_FAILURE; case 0: /* Fils */ /*on ferme l'entrée du tube 2 le fils ne peut plus lire sur le tube 2*/ close(tube2[0]); /*on ferme la sortie du tube 1 le fils ne peut plus écrire sur le tube 1*/ close(tube[1]); printf("Fils :j'écris \"Salut papa\"\n"); write(tube2[1], "Salut papa", 31); printf("J'attend une réponse papoupnet\n"); read(tube[0], message, 31); printf("Fils : je lis 31 caractères dans le tube\n"); printf("Fils : j'ai lu '%s'\n", message); break; default: /* Père */ /*on ferme l'entrée du tube 1 le fils ne peut plus lire sur le tube 1*/ close(tube[0]); /*on ferme la sortie du tube 2 le fils ne peut plus écrire sur le tube 2*/ close(tube2[1]); printf("Père : je lis 31 caractères dans le tube\n"); read(tube2[0], message, 31); printf("Père : j'ai lu '%s'\n", message); printf("Père: message1 du Fils lu, j'envoi message2\n"); write(tube[1], "Salut filston", 31); break; } return EXIT_SUCCESS; } TRACE : Père : je lis 31 caractères dans le tube Père : j'ai lu 'Salut papa' Père: message1 du Fils lu, j'envoi message2 Fils :j'écris "Salut papa" J'attend une réponse papoupnet Fils : je lis 31 caractères dans le tube Fils : j'ai lu 'Salut filston' 3 Communication du père avec 2 fils /* ---------------------------------------------------------------------------
  • communication circulaire :
_______________________ | | v ^ pere fils 1 | ^ | | |-------> fils 2--------
  • Entrées : aucune
  • Sorties : traces à l'écran
  • --------------------------------------------------------------------------*/
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> /* Pour pid_t (fork, getpid, getppid) */ int main(void) { pid_t ident, ident2; int tube[2]; int tube2[2]; int tube3[2]; /* les deux descripteurs associés au tube */ char message[20]; /* Une chaîne pour stocker les messages lus
  • dans le tube */
if (pipe(tube) != 0) /* Création du tube 1 */ { perror("pipe"); return EXIT_FAILURE; } if (pipe(tube2) != 0) /* Création du tube 2 */ { perror("pipe"); return EXIT_FAILURE; } if (pipe(tube3) != 0) /* Création du tube 3 */ { perror("pipe"); return EXIT_FAILURE; } ident = fork(); /* Création du fils1 */ switch (ident) { case -1: perror("fork"); return EXIT_FAILURE; case 0: /* Fils 1 lit sur tube2[0] et écrit sur tube3[1]*/ close(tube3[0]); close(tube2[1]); close(tube[0]); close(tube[1]); write(tube3[1], "salut papa\0", 60); read(tube2[0], message, 60); printf("FILS1:lit: %s de FILS2\n", message); break; default: /* Père */ ident2 = fork(); /* Création du fils2 */ switch (ident2) { case -1: perror("fork"); return EXIT_FAILURE; case 0: /* Fils2 */ close(tube2[0]); close(tube[1]); close(tube3[0]); close(tube3[1]); read(tube[0], message,6); printf("FILS2:lit: %s de PERE\n", message); write(tube2[1], "salut frere papa te dit bonjour",32); break; default: close(tube[0]); close(tube3[1]); close(tube2[0]); close(tube2[1]); read(tube3[0], message, 32); printf("PERE:lit: %s de FILS1\n", message); write(tube[1], "salut",6); break; } break; } return EXIT_SUCCESS; } TRACE : PERE:lit: salut papa de FILS1 FILS1:lit: salut frere papa te dit bonjour de FILS2 FILS2:lit: salut de PERE 4 E/S /* ---------------------------------------------------------------------------
  • les tubes Unix.
  • simulation des pipe UNIX du shell
  • Entrées : aucune
  • Sorties : traces à l'écran
  • --------------------------------------------------------------------------*/
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> /* Pour pid_t (fork, getpid, getppid) */ int main(void) { pid_t pid; int tube[2]; /* les deux descripteurs associés au tube */ pipe(tube); if((pid = fork()) == 0) {/* FILS */ /*on ferme stdout*/ fclose(stdout); /*on le remplace par tube [1]*/ dup(tube[1]); /*on ferme tube[0] pour ne pas lire dans le tube mais dans stdin*/ close(tube[0]); execlp("who","who",NULL);} else {/* PERE */ /*on ferme stdin*/ fclose(stdin); /*on le remplace par le tube[0]*/ dup(tube[0]); /*on ferme le tube [1] pour ne pas écrire dans le tube mais sur stdout*/ close(tube[1]); execlp("cut","cut","-c","1-10",NULL);} return EXIT_SUCCESS; } TRACE : $who | cut -c 1-10 tbonin : tbonin p tbonin p tube5 : tbonin : tbonin p tbonin p 4 bis TRACE : $ adesport /* ---------------------------------------------------------------------------
  • Entrées : aucune
  • Sorties : traces à l'écran
  • --------------------------------------------------------------------------*/
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> /* Pour pid_t (fork, getpid, getppid) */ int main(void) { pid_t pid,pidSort,pidTest; int tube[2],tubeSort[2]; pipe(tube); if((pid = fork()) == 0) {/* FILS */ /*on ferme stdout*/ fclose(stdout); /*on le remplace par tube [1]*/ dup(tube[1]); /*on ferme tube[0] pour ne pas lire dans le tube mais dans stdin*/ close(tube[0]); execlp("who","who",NULL);} else {/* PERE */ pipe(tubeSort); if((pidSort = fork()) == 0) {/* FILS 2*/ /*on ferme stdin*/ fclose(stdin); /*on le remplace par le tubeSort[0]*/ dup(tubeSort[0]); close(tube[0]); close(tube[1]); close(tubeSort[1]); execlp("sort","sort","-u",NULL); } /*on ferme stdin*/ fclose(stdin); /*on le remplace par le tube[0]*/ dup(tube[0]); /*on ferme stdout*/ fclose(stdout); dup(tubeSort[1]); /*on ferme le tube [1] pour ne pas écrire dans le tube mais sur tubeSort[1]*/ close(tube[1]); /*on ferme le tubeSort [0] pour ne pas lire dans le tube mais sur tube[0]*/ close(tubeSort[0]); execlp("cut","cut","-c","1-9",NULL);} return EXIT_SUCCESS; }

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.