IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

mkfifo() ou pipe()?


Sujet :

Linux

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 67
    Points : 42
    Points
    42
    Par défaut mkfifo() ou pipe()?
    Bonjour à tous,

    Je me suis lancé récemment dans la programmation Unix, et en ce moment je suis entrain de faire un petit programme pour bien visualiser le fonctionnement des tubes (j'ai déja essayer avec des exercices basiques : genre écriture d'une chaîne et réception de l'autre "coté").

    Voilà ma question :
    Pour faire communiquer deux processus à travers un pipe, est-on obligé d'utiliser la primitive pipe() (et pas mkfifo())??

    Merci

  2. #2
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Non, rien ne t'empêche d'utiliser un tube nommé avec mkfifo().
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ggwtf Voir le message
    Bonjour à tous,

    Je me suis lancé récemment dans la programmation Unix, et en ce moment je suis entrain de faire un petit programme pour bien visualiser le fonctionnement des tubes (j'ai déja essayer avec des exercices basiques : genre écriture d'une chaîne et réception de l'autre "coté").

    Voilà ma question :
    Pour faire communiquer deux processus à travers un pipe, est-on obligé d'utiliser la primitive pipe() (et pas mkfifo())??

    Merci


    En fait, la primitive pipe() te crée un canal de communication totalement en mémoire. L'avantage est qu'il n'y a rien sur le disque. L'inconvénient, c'est que seuls deux processus liés père/fils pourront communiquer par ce canal.

    La primitive mkfifo() te crée un fichier tube (fichier de type "p"). L'avantage c'est que deux processus totalement indépendants pourront communiquer à travers ce canal. L'inconvénient c'est que cela passe par la création d'un fichier sur le disque.

    A partir de là, à toi de voir ce qui t'intéresse le mieux.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 67
    Points : 42
    Points
    42
    Par défaut
    Merci pour vos réponses. Je vois plus clair. J'ai tester simplement avec pipe() par contre je suis un peu perdu avec mkfifo() même si ça s'apparente à une simple gestion de fichier visiblement, je ne sais pas trop comment m'y prendre pour écrire et faire passer une séquence tapée au clavier... (fgets?)

    Une autre question également: y a t-il moyen de passer en paramètre le nom du tube (avec mkfifo), en utilisant les paramètres de la fonction main()?
    Si oui, comment utiliser argv[]?

    Merci encore!

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ggwtf Voir le message
    Merci pour vos réponses. Je vois plus clair. J'ai tester simplement avec pipe() par contre je suis un peu perdu avec mkfifo() même si ça s'apparente à une simple gestion de fichier visiblement, je ne sais pas trop comment m'y prendre pour écrire et faire passer une séquence tapée au clavier... (fgets?)
    Ben une fois que tu as ton fichier, tu l'ouvres avec fopen() ou open() au choix
    Si tu utilises fopen(), te suffit de faire un fputs(fp, chaine saisie). Si tu utilises open(), faut que tu fasses un write(ident_fichier, chaine_saisie, nb_caractères_chaine + 1).

    De l'autre coté, tu peux utiliser fopen() ou open() pareil (et c'est pas parce que tu utilises fopen() d'un coté que tu dois utiliser fopen() de l'autre, c'est totalement indépendant).
    Si tu utilises fopen(), alors tu récupères la chaine saisie via un fgets(fp, buffer, taille_buffer). Et si tu utilises open() alors tu récupères la chaine saisie via un read(ident_fichier, buffer, taille_buffer)

    Dernier truc: le "+ 1" à l'écriture sert juste à envoyer au fifo le caractère '\0' qui marque la fin de chaine donc tu le récupères de l'autre coté sans problème (puisque pour read il s'agit d'un caractère comme les autres). Mais tu n'es pas obligé de l'envoyer à l'écriture si tu prends soin de le placer toi-même du coté lecture. C'est toi qui voit.

    Citation Envoyé par ggwtf Voir le message
    Une autre question également: y a t-il moyen de passer en paramètre le nom du tube (avec mkfifo), en utilisant les paramètres de la fonction main()?
    Si oui, comment utiliser argv[]?
    argv[] est un tableau de chaines (donc un tableau de pointeurs puisqu'une chaine c'est un pointeur) qui contient chaque argument passé au programme lors de son appel.
    Puisque argv[] est un tableau de pointeurs, (un char *[]), alors chaque "argv[n]" devient un simple pointeur (un char*). Puisque la fonction mkfifo() attend un char* et que chaque argv[x] est un char*, il te suffit de passer à la fonction le argv[x] qui est sensé contenir le nom du fichier et pis c'est tout.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 23
    Points : 16
    Points
    16
    Par défaut
    bonjour, je profite de ce poste, car je suis comme ggwtf en train d'essayer une manipulation basique d'un FIFO.

    Et je rencontre un problème à l'ouverture en ecriture de mon tube que je ne comprends pas trop.

    mon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    wr=open(tube,O_WRONLY | O_NDELAY);
    me renvoye -1 ... En comparant mon code à d'autre exemple je ne vois pas ou est ma faute..


    Je ne suis pas sur d'avoir également compris.Suis je à chaque fois obligé d'ajouter O_NDELAY lorsque j'ouvre un tube vide ?

    Merci d'avance

    Voici mon bout de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <errno.h>
     
     
    main (void)
    {
     
     
      char *tube = "tube";
      char mot[21];
      int wr=0;
     
        if(mkfifo (tube, 0666) ==0) /* creation tube avec droit lecture/ecriture*/
    	{
    		printf("ok");
    	}
        else 
    	{
    		if(errno == EEXIST) printf("fichier existe deja \n");		
    		else printf("probl");
    	}
     
    	wr=open(tube,O_WRONLY | O_NDELAY);
    	if(wr<0)
    	{
    		printf("error a l'ouverture");
     
    	}
    	else
    	{
    		printf("inserez un mot a envoyer");
    		scanf("%s",mot);	
    		if(write(tube,mot,strlen(mot))<0)
    		{
    			printf("erreur ecriture");
    		}
    		else
    		{
    			puts(mot);
    		}
    	}
    	close(wr);
     
      return (0);
    }

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wokba Voir le message
    bonjour, je profite de ce poste, car je suis comme ggwtf en train d'essayer une manipulation basique d'un FIFO.

    Et je rencontre un problème à l'ouverture en ecriture de mon tube que je ne comprends pas trop.

    mon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    wr=open(tube,O_WRONLY | O_NDELAY);
    me renvoye -1 ... En comparant mon code à d'autre exemple je ne vois pas ou est ma faute..


    Je ne suis pas sur d'avoir également compris.Suis je à chaque fois obligé d'ajouter O_NDELAY lorsque j'ouvre un tube vide ?
    Affiche donc strerror(errno) au format "%s". T'auras un beau message d'erreur indiquant la cause de l'échec de l'ouverture. Par ailleurs si t'arrives pas à le créer, c'est inutile d'aller plus loin donc tu pourrais mettre un exit() dans le premier else.

    Pour ta 2° question, le NDELAY évite le blocage inhérent aux pipes lorsqu'un processus tente d'y écrire sans qu'il y ait un processus pour lire et inversement mais cette option n'est pas obligatoire. D'ailleurs la fonction "blocage" est souvent un outil intéressant car elle permet d'éviter les accès concurrents...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 23
    Points : 16
    Points
    16
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Affiche donc strerror(errno) au format "%s". T'auras un beau message d'erreur indiquant la cause de l'échec de l'ouverture. Par ailleurs si t'arrives pas à le créer, c'est inutile d'aller plus loin donc tu pourrais mettre un exit() dans le premier else.

    Pour ta 2° question, le NDELAY évite le blocage inhérent aux pipes lorsqu'un processus tente d'y écrire sans qu'il y ait un processus pour lire et inversement mais cette option n'est pas obligatoire. D'ailleurs la fonction "blocage" est souvent un outil intéressant car elle permet d'éviter les accès concurrents...

    Merci pour l'aide, conseil et explication

    Il m'affiche comme erreur "No such Device or Address",
    après quelques recherches, une des explications trouvées pour cetter erreur était un probleme de droit ecriture ou lecture..

    Bref j'ai changer l'ouverture de mon FIFO, de O_WRONLY a O_RDWR pour passer en lecture et écriture.. et plus d' erreur pour l'ouverture du fichier. Est ce bien normal ? Je n'ais pourtant besoin que d'ecrire..

    mais ca marche, maintenant

Discussions similaires

  1. Pipes UNIX avec os.mkfifo
    Par gaston_lagaffe dans le forum Général Python
    Réponses: 1
    Dernier message: 01/11/2006, 11h54
  2. Pipes - Comment faire ?
    Par Neitsa dans le forum x86 32-bits / 64-bits
    Réponses: 4
    Dernier message: 11/12/2003, 05h44
  3. [C/S] Boken Pipe
    Par Gogoye dans le forum POSIX
    Réponses: 4
    Dernier message: 23/10/2003, 10h48
  4. Réponses: 3
    Dernier message: 21/08/2003, 14h47
  5. Problème : bloquage d'un pipe
    Par Nicaisse dans le forum POSIX
    Réponses: 10
    Dernier message: 24/07/2003, 11h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo