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

C Discussion :

Communication inter-processus mémoire partagé problème du lecteur/ecrivain


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    fdf
    Inscrit en
    Novembre 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : fdf

    Informations forums :
    Inscription : Novembre 2014
    Messages : 20
    Points : 17
    Points
    17
    Par défaut Communication inter-processus mémoire partagé problème du lecteur/ecrivain
    Bonsoir,

    D'abord l'écrivain bloque le semaphore disons "peut-écrire" à 0, (précédemment initialisé à 1).
    Quand l'écrivain a fini d'écrire dans le segment de mémoire partagé (buffer), il incrémente le sémaphore, disons "peut_lire" à 1 (préalablement initialisé à 0).

    Les semaphores sont dans un structes shared_mem, et le lecteur fait appel à une fonction lire_dans_shm(struct shared_mem *shm).
    Même chose pour le écrivain mais ecrire_dans_shm(struct shared_mem *shm)

    Quand j'affiche la valeur du semaphore "peut_lire" dans la fonction lire_dans_shm (fonction située just avant le exit(EXIT_SUCCES) du lecteur.c) il vaut 0 avant le sem_wait(&peut_lire) alors que comme on vient de le voir il doit valoir 1 (incrémentation de l'écrivain) ... ducou le lecteur reste bloque sur sem_wait(&peut_lire) et n'affiche pas le contenu du buffeur (seciton critique).

    Quand l'écrivain a finit d'écrire dans le shm (écrire_dans_shm dans écrivain.c) comment le lecteur intervient pour lire grâce à sa fonction peut_lire_dans_shm dans lecteur.c, à quel moment, ou alors il faut faire appel à autre chose dans le code de l'écrivain pour que les lecteurs se lance (exec) ?

    Comment s'est possible que plusieurs lecteur se lance juste parce que on a créer un segment de mémoire partagé, le fait d'y accéder ?


    Merci

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    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 374
    Points : 23 631
    Points
    23 631
    Par défaut
    Bonjour,

    Avant toute chose, est-ce que tu travailles sous un Unix (type SysV) ou sous Linux, ou bien développes-tu avec un OS qui n'a rien à voir ? Et deuxième question : est-ce que tu utilises bien les IPC SysV5 (semget, shmget, etc…) ? Parce que si c'est le cas, toutes ces ressources ont un espace propre et tes sémaphores n'ont pas à se trouver « dans le segment de mémoire partagée ». Si ce n'est pas le cas et que tu es en train d'implémenter des mutex pour partager l'accès à la ressource, alors il y a d'autres vérifications à faire (accès concurrents).

    Ensuite, ça dépend de l'exercice que tu cherches à implémenter. Soit tu veux faire du message passing et faire en sorte qu'il n'y ait qu'un seul lecteur et qu'un seul écrivain au maximum à un moment donné, soit tu veux implémenter une file, et faire en sorte qu'elle soit bloquée en lecture si elle est vide et bloquée en écriture si elle est pleine. Selon le cas, les sémaphores vont être grosso-modo les mêmes mais ils ne seront pas manipulés dans les mêmes conditions.

  3. #3
    Membre à l'essai
    Homme Profil pro
    fdf
    Inscrit en
    Novembre 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : fdf

    Informations forums :
    Inscription : Novembre 2014
    Messages : 20
    Points : 17
    Points
    17
    Par défaut
    Bonjour,

    Je travail sous linux xubuntu.Pour le segment de mémoire partagé j'utilise : shm_open , ftruncate, mmap.
    Il s'agit de créer un système serveur/client, tous deux des executables.
    Il peut y avoir plusieurs client chacun d'eux créer une mémoire partagé que le serveur va ouvrire et y écrire.
    détail pour chaque client :
    Le client créer un segment de mémoire partagé envoi une requête au serveur via un tube nommé, le serveur récupère la requête créer un thread qui ouvre le segment de mémoire et le projette avec mmap, ensuite il initialise les semaphores wsem (write semaphore : peut écrire) à 1 vue qu'on va d'abord écrire, et rsem (peut lire) à 0 ensuite il créer un tube anonyme puis fork().
    Le fils traite la requête (informations sur un processus ou utilisateur) redirige sa sortie standard vers tube[1], le père y lit et écrit dans le segment de mémoire partagé.
    Ma structure pour le segment de mémoire partagé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define BUFFER_SIZE 4096
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct shared_mem {
      sem_t wsem;  // write semaphore
      sem_t rsem;  // read semaphore
      ssize_t count;  //nombre de donnés écrit par le serveur et lu par le client
      char buffer[BUFFER_SIZE];  
    } shared_mem;

    Fonction du serveur, appelé dans le père pour écrire dans le buffer du shm.
    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
     
    void write_answer(shared_mem *shm, int *tube) { 
    bool first_loop = true;
      do {
        if (sem_wait(&shm -> wsem) == -1) {
          perror("sem_wait");
          exit(EXIT_FAILURE);
        }
        if (shm -> count != 0 || first_loop) {
          if((shm -> count = read(tube[0], shm -> buffer, 
    	 BUFFER_SIZE)) == -1) {
    	 perror("read");
    	 exit(EXIT_FAILURE);
        }
      } 
      printf("Le serveur a écrit dans le buffer : %s\n", shm -> buffer);
      first_loop = false;
      if (sem_post(&shm -> rsem) == -1) {
        perror("sem_post");
        exit(EXIT_FAILURE);
      }
     } while(shm -> count != 0);
    }
    utilisé à ce niveau par le père dans la routine du thread créer.

    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
     
      default :	
        if (close(tube[1]) == -1) {
    	perror("close");
    	exit(EXIT_FAILURE);
       }
      //Ecriture  la réponse dans le shm
      write_answer(shm, &tube[0]);
      sleep(3);
      if (close(tube[0]) == -1) {
    	perror("close");
    	exit(EXIT_FAILURE);
      }
      if(wait(NULL) == -1) {
          perror("wait");
          pthread_exit(NULL);
      }
      pthread_exit(NULL);
    }


    La fonction qui suit a été utilisé dans client.c, juste après l'envoi des requêtes via le tube nommé au serveur et juste avant le exit(EXIT_SUCCESS) du main.

    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
     
    void get_answer(shared_mem *shm) {
      do {	
        if(sem_wait(&shm -> rsem) == -1) {
          perror("sem_wait");
          exit(EXIT_FAILURE);
        }
        if (shm -> count != 0) {
          if(write(STDOUT_FILENO, shm -> buffer, shm -> count) 
    	  != shm -> count) {
    		fprintf(stderr, "erreur: réponse complète non récuperé.");
                    exit(EXIT_FAILURE);
    	}
       }
       if(sem_post(&shm -> wsem) == -1) {
         perror("sem_post");
         exit(EXIT_FAILURE);
      }
     } while (shm -> count != 0);
    }
    Si besoin je peux t'envoyer par message l'archive de mon projet commentée

  4. #4
    Membre à l'essai
    Homme Profil pro
    fdf
    Inscrit en
    Novembre 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : fdf

    Informations forums :
    Inscription : Novembre 2014
    Messages : 20
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Bonjour,

    et faire en sorte qu'il n'y ait qu'un seul lecteur et qu'un seul écrivain au maximum à un moment donné, soit tu veux implémenter une file, et faire en sorte qu'elle soit bloquée en lecture si elle est vide et bloquée en écriture si elle est pleine. Selon le cas, les sémaphores vont être grosso-modo les mêmes mais ils ne seront pas manipulés dans les mêmes conditions.
    Donc ça serait plus le problème du Producteur-Consommateur ?

    et faire en sorte qu'il n'y ait qu'un seul lecteur et qu'un seul écrivain au maximum à un moment donné
    Dans mon cas on a plusieurs lecteur et chacun a sa propre memoire partagé, mais lecteur + leur memoire associée correspondent tous au même écrivain.
    Vue que l'écrivain traite les requêtes de chaque lecteur, dans leur propre mémoire partagé est-ce qu'on peut dire finalement qu'on a un message passing ?

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

Discussions similaires

  1. Communication inter-processus et pause()
    Par jsebfranck dans le forum POSIX
    Réponses: 10
    Dernier message: 14/02/2008, 14h52
  2. [windows] Communication inter-processus
    Par litbos dans le forum Windows
    Réponses: 6
    Dernier message: 16/01/2007, 09h13
  3. [Perl] communication Inter-Processus
    Par MarneusCalgarXP dans le forum Langage
    Réponses: 15
    Dernier message: 14/08/2006, 22h43
  4. [débutant] Communication inter-processus
    Par tooney dans le forum C
    Réponses: 3
    Dernier message: 29/12/2005, 20h48
  5. communication inter-processus
    Par benoit70 dans le forum MFC
    Réponses: 1
    Dernier message: 14/04/2005, 09h55

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