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

Bibliothèque standard C Discussion :

Pourquoi read() est non bloquant


Sujet :

Bibliothèque standard C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 16
    Points : 13
    Points
    13
    Par défaut Pourquoi read() est non bloquant
    Bonjour,

    Je cherche à comprendre les communications inter-processus avec les pipe nommés.
    Je fais face à un problème : si j'ai bien compris la lecture est bloquante. Pourtant dans mon code, les instructions après read(), dans le processus fils lecteur, sont exécutées.
    Mais moi je voudrais que read soit bloquant...

    Merci d'avance pour votre aide !


    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <sys/types.h>
     
     
    #define TUBE "f.fifo"
     
    int main()
    {
      char msg[256];
      int tube, taille;
      mkfifo(TUBE, S_IRWXU | S_IRWXG | S_IRWXO);
     
      if (fork() == 0)// Processus lecteur
        {
          printf("Je suis le fils de pid %d\n", getpid());
          tube = open(TUBE, O_RDONLY);
          printf("Lecture dans le pipe\n");
          printf("Appelle de read\n");
          taille = read(tube, (void*)msg, 256);
          printf("msg : %s\n", msg);
          printf("Taille de ce qui a ete lu : %d\n", taille);
        }
      else { // Processus ecrivain
        printf("Je suis le pere de pid %d\n", getpid());
        tube = open(TUBE, O_WRONLY);
      }
     
      return EXIT_SUCCESS;
    }

  2. #2
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Ton programme ne fait.. rien. Le flux a donc de fortes chances d'être fermé au moment où l'appel système est réalisé, puisque ton processus producteur termine immédiatement. Un simple timer devrait mettre en évidence le fait que read est bien bloquant ici.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 16
    Points : 13
    Points
    13
    Par défaut
    Tout d'abord merci pour ta réponse !
    Le processus producteur termine en effet immédiatement, mais pourtant je pensais que pour fermer le flux il fallait le faire explicitement avec l'appel à close(). Le flux se ferme tout seul donc ?
    Et je ne vois pas très bien comment je pourrais le voir avec un timer ? Peux-tu m'éclairer ?

    EDIT: Je crois que j'ai compris ce que tu voulais par timer. Dans le processus producteur j'ai fait un appel à sleep(), et en effet la lecture bloquante est bien mise en évidence. En revanche je suis bien curieux de comprendre cette histoire de close()...

  4. #4
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Je suis un peu rouillé en programmation système mais je pense qu'il doit se passer la chose suivante :

    1. les descripteurs du producteur sont fermés par le système d'exploitation en fin d'exécution - per le protocole requis par POSIX (clic !) ;
    2. puisque plus aucun processus n'a de descripteur sur le pipe en écriture, le consommateur se retrouve en EOF - per le comportement de read (clic !), cf. When attempting to read from an empty pipe or FIFO.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 16
    Points : 13
    Points
    13
    Par défaut
    Ah oui d'accord, ça doit être ça. C'est plus clair maintenant. Merci pour ton aide !

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 400
    Points : 23 778
    Points
    23 778
    Par défaut
    Citation Envoyé par Enalde Voir le message
    Le processus producteur termine en effet immédiatement, mais pourtant je pensais que pour fermer le flux il fallait le faire explicitement avec l'appel à close(). Le flux se ferme tout seul donc ?
    En fait, il faut surtout prendre le problème dans l'autre sens : si le descripteur reste ouvert mais que le processus disparaît, que va-t-il devenir ? Et comment faire pour le récupérer ensuite (ne serait-ce que pour pouvoir le refermer en bonne et due forme). Et enfin, que deviennent les correspondants qui jusque là communiquaient normalement avec lui ?

    Le bon sens nous laisse donc penser que le système d'exploitation va laisser au processus la responsabilité de gérer comme il l'entend toutes les ressources tant qu'il est là pour le faire mais s'il meurt, le système va AU MOINS recycler proprement ce qui a été alloué auprès de lui. C'est valable aussi pour les fuites de mémoire, par exemple : quand on appelle malloc(), c'est bien le système qui gère lui-même le pool de mémoire disponible en tenant référence des plages allouées ET des processus auxquels elles ont été attribuées. Donc un processus peut avoir une fuite de mémoire et finir par l'accaparer entièrement tant qu'il est en vie mais dès qu'il meurt, le système les marque forcément comme à nouveau disponibles.

    Évidemment, ce n'est pas une raison pour omettre volontairement de le faire. Il y a eu un temps où l'abandon pur et simple de tout ce qui a été alloué en fin de programme a été une mode, mais ça n'a pas duré longtemps…

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

Discussions similaires

  1. Pourquoi "goto" est déconseillé ?
    Par Melchisedec dans le forum Débuter
    Réponses: 20
    Dernier message: 30/05/2020, 16h24
  2. Socket - read non bloquant alors qu'il devrait être bloquant
    Par _LittleFlea_ dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 04/04/2011, 10h54
  3. Read non bloquant, repérer saisie backspace
    Par firemax dans le forum C
    Réponses: 7
    Dernier message: 18/05/2008, 10h00
  4. Pourquoi le Wait Time per Read est elevé ?
    Par lanbok dans le forum SAP
    Réponses: 4
    Dernier message: 21/01/2008, 15h52
  5. [API] Communication série NON-bloquante : OVERLAPPED/Thread
    Par Rodrigue dans le forum C++Builder
    Réponses: 2
    Dernier message: 07/11/2003, 13h43

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