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 :

pipe nommé read boucle de façon infinie


Sujet :

Linux

  1. #1
    Membre habitué
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2008
    Messages : 289
    Points : 151
    Points
    151
    Par défaut pipe nommé read boucle de façon infinie
    Bonjour,
    j'ai besoin d'utiliser un pipe nommé dans une application. Chose que je n'ai jamais mis en oeuvre.
    J'ai donc un processus en attente de données de la part d'autres processus via une fifo:
    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
     
    //Créer un pipe nommé
        retour = mkfifo("echange.fifo", 0644);
        if(retour < 0)
        {
            perror("mkfifo");
            exit(-1);
        }
        //Ouvrir le pipe nommé en lecture
        fd_fifo = open("echange.fifo", O_RDONLY);
        if(fd_fifo < 0)
        {
            perror("open fifo");
            exit(-3);
        }
     
        //Attendre que des données arrivent dans la FIFO (nom + code)
        while(1)
        {
            //bloquer sur la lecture
            read(fd_fifo, data, sizeof(data));
            printf("FIFO receive: %s\n", data);
        }
    Un "client" peut utiliser cette fifo pour lui passer des données:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //Utiliser le pipe nommé relié au processus d'identification pour lui passer nom et code
        fd_fifo = open("echange.fifo", O_WRONLY);
        if(fd_fifo < 0)
        {
            perror("open fifo");
            exit(-2);
        }
        write(fd_fifo, argv[1], strlen(argv[1])+1);
        write(fd_fifo, argv[2], strlen(argv[2])+1);
        close(fd_fifo);
    Mon processus lecteur reçoit bien le contenu des deux write. Mais la boucle while(1) tourne ensuite en permanence sur la lecture du dernier message reçu SAUF si je ne fais pas le close(fd_fifo) côté écrivain.
    Je ne comprend pas pourquoi le dernier read ne vide pas complètement la fifo.
    Pourquoi est-ce que close() perturbe la lecture?

    Merci de vos réponses.

  2. #2
    Membre habitué
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2008
    Messages : 289
    Points : 151
    Points
    151
    Par défaut
    Bonjour,
    je me répond à moi-même.
    Ca ne fonctionne toujours pas, j'ai donc modifié mon code pour essayer de comprendre au mieux ce qui se passe.
    Processus lecteur:
    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
     
    //Créer un pipe nommé
        retour = mkfifo("echange.fifo", 0644);
        if(retour < 0)
        {
            perror("mkfifo");
            exit(-1);
        }
        printf("mkfifo ok\n");
        //Ouvrir le pipe nommé en lecture
        fd_fifo = open("echange.fifo", O_RDONLY);
        if(fd_fifo < 0)
        {
            perror("open fifo");
            exit(-3);
        }
        printf("open ok\n");
     
        //Attendre que des données arrivent dans la FIFO (nom + code)
        while(1)
        {
            printf("Attendre une donne: ");
            i = 0;
            //bloquer sur la lecture
            while(read(fd_fifo, &carcou, sizeof(char)) > 0)
            {
                data[i] = carcou;
                ++i;
            }
            data[i] = '\0';
            printf("FIFO receive: %s\n", data);
            sleep(1);
        }
    Je fais une réception octet par octet

    Processus écrivain:
    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
     
    //Utiliser le pipe nommé relié au processus d'identification pour lui passer nom et code
        fd_fifo = fopen("echange.fifo", "w");
        if(fd_fifo == NULL)
        {
            perror("fopen fifo");
            exit(-2);
        }
     
        scanf("%c", &choix);
        while(getchar() != '\n');
        fwrite(argv[1], sizeof(char), strlen(argv[1])+1, fd_fifo);
        fflush(fd_fifo);
     
        scanf("%c", &choix);
        while(getchar() != '\n');
        fwrite(argv[2], sizeof(char), strlen(argv[2])+1, fd_fifo);
        fflush(fd_fifo);
     
        scanf("%c", &choix);
        fclose(fd_fifo);
        printf("Bye!\n");
    Je m'aperçois que le lecteur bloque sur la fonction open() tant que l'écrivain n'a pas exécuté son fopen().
    Par la suite, le lecteur affiche ce qu'il a lu seulement quand l'écrivain ferme la fifo de son côté.
    Je n'ai jamais mis en place un tube nommé et je ne retrouve pas le fonctionnement usuel des fonctions open, read, write ou close
    que j'ai déjà utilisé sur des fichiers disque ou des tubes anonymes.
    Merci pour vos réponses.

  3. #3
    Membre habitué
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2008
    Messages : 289
    Points : 151
    Points
    151
    Par défaut
    Je continue à me répondre à moi-même (solitude...).
    En utilisant un select suivi d'un read, ça fonctionne parfaitement pour ce dont j'ai besoin.
    Pourquoi passer par un select ? Grand mystère...
    Dans tous les exemples consultés, je ne l'ai jamais vu.

  4. #4
    Membre régulier
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Avril 2015
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2015
    Messages : 46
    Points : 108
    Points
    108
    Par défaut
    Selon la page de manuel de mkfifo : https://linux.die.net/man/3/mkfifo
    However, it has to be open at both ends simultaneously before you can proceed to do any input or output operations on it. Opening a FIFO for reading normally blocks until some other process opens the same FIFO for writing, and vice versa.

    Par contre il est aussi dit ici : https://linux.die.net/man/4/fifo
    A process can open a FIFO in non-blocking mode. In this case, opening for read only will succeed even if noone has opened on the write side yet; opening for write only will fail with ENXIO (no such device or address) unless the other end has already been opened.
    Donc il faudrait que ton listener fasse son open avec l'option : O_NONBLOCK
    comme tu peux le voir icc : https://linux.die.net/man/2/open

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Boucle de redirection infinie - AliasMatch ?
    Par Kaerañ dans le forum Apache
    Réponses: 2
    Dernier message: 25/06/2008, 15h02
  2. Lecture de pipe nommé sur Linux
    Par mulot49 dans le forum Langage
    Réponses: 1
    Dernier message: 29/10/2007, 15h02
  3. Faire une boucle d'attente infinie
    Par ego dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 13/11/2006, 23h14
  4. Réponses: 14
    Dernier message: 31/08/2005, 17h21
  5. Réponses: 3
    Dernier message: 16/03/2004, 16h42

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