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 :

[segment de memoire partagée]


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    88
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 88
    Points : 59
    Points
    59
    Par défaut [segment de memoire partagée]
    Bonsoir,

    Je suis en train de créer un segment de memoire pour pouvoir partager une variable entre un processus pere et son fils, et ma variable se duplique... or elle ne devrait pas,

    Voici le code associé,

    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    #include<stdio.h>
    #include <sys/ipc.h>
    #include<sys/types.h>
    #include<sys/shm.h>
    #define places_max 20
    #define cle (key_t) getuid()
    int places_reservees=0;
    int num; // numero du segment de memoire
     
    void reservationPlaces(int nb)
    {
      shmat(num, 0, 0);
      printf("Vous voulez reserver %d place(s)\n", nb);
      if(places_reservees+nb<=places_max)
        {
          places_reservees+=nb;
          printf("La reservation a ete faite.\n");
        }
      else
        {
          printf("La reservation ne peut pas se faire car on depasse le nombre maximum de places.\n");
        }
    }
     
    int main()
    {
      int n;                // variable qui contient le nombre de places qu'un processus veut reserver
      int pid;              // valeur de retour de la primitive fork
      int i, *pint;
      int addr1, addr2;
      struct shmid_ds *buf;
     
      printf("Voici le nombre de places disponibles actuellement : %d\n", places_max-places_reservees); 
     
      // Allouer un segment de memoire partagee
      if((num = shmget(cle, 128*1024, IPC_EXCL|IPC_CREAT|0666)) == -1)
        {
          perror("Probleme de creation du segment de memoire\n");
          exit(1);
        }
      else printf("Segment d'identificateur %d cree\n", num);
     
      // Controler la memoire partage
      if(shmctl(num,IPC_STAT,buf)==-1)
        {
          perror("Probleme lors du controle du segment de memoire\n");
          exit(2);
        }
     
      // Creation du processus fils
      pid = fork();
     
      if(pid < 0)  // pb
        {
          perror("Pb de creation du fils\n");
          exit(1);
        }
      if(pid == 0) // fils
        {
          addr1 = (int*)shmat(num, 0, 0);
     
          if (&addr1 == -1)
    	{
    	  perror("attachement impossible\n");
    	  exit(1);
    	}
     
          n = 19;
          num = n;
          reservationPlaces(n);
     
          if(shmdt((int)(const void *)addr1==-1))
    	{
    	  perror("detachement impossible\n");
    	  exit(2);
    	}
     
     
        }
      else         // pere
        {
          addr2 = (int*)shmat(num, 0, 0);
     
          if (&addr2 == -1)
    	{
    	  perror("attachement impossible\n");
    	  exit(3) ;
    	}
     
          n = 8;
          num = n;
          reservationPlaces(n);
     
          if(shmdt((int)(const void *)addr2)==-1)
    	{
    	  perror("detachement impossible\n");
    	  exit(4) ;
    	}
     
     
        }
     
      // attendre la fin des processus
      while(wait(NULL)!=-1);
     
      printf("Voici le nombre de places disponibles actuellement : %d\n", places_max-places_reservees); 
      exit(0);
     
     if (shmctl(num,IPC_RMID,buf) == -1)
       {
         perror("Erreur de destruction du segment de memoire\n") ;
         exit(5) ;
       }
     
      return 0;
    }
    Merci de voir ce que vous pouvez faire,

    Ninie

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Déjà, ceci: est évidemment une erreur (un & de trop, et ce test est fait plus d'une fois).

    Je pense que tu aurais du avoir un avertissement à la compilation...

    Essaie de compiler avec ces paramètres:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    -Wall -Wextra -O2 -Wwrite-strings -std=c99
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    88
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 88
    Points : 59
    Points
    59
    Par défaut
    Merci à toi.

    Oui c'est vrai, je l'ai changé à la dernière minute lol
    Mais mon problème n'est pas là. Je me retrouve avec une exécution identique avec ou sans segment de mémoire... normalement ici ma variable "places_reserveees" ne devrait pas être dupliquée au niveau du processus fils. Or elle l'est puisque je n'ai pas une bonne mise à jour de cette variable.

    Quelqu'un voit-il d'où ça vient? Je me pense que la primitive shmat est mal utilisée, je ne sais pas

    Merci à vous de m'aider!

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 17
    Points : 20
    Points
    20
    Par défaut
    En fait ton int num; crées ou recherches ton segment de mémoire.
    Ensuite tout processus désirant partager cette zone de mémoire doit de le faire savoir en utilisant
    shmat(...);

    donc dans ton prog remplaces
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int places_reservees =0; par int*places_reservees;
    puis une fois que tu as crée l'espace de mém avec shmget:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      if((places_reservees=(int *)shmat(shmid,NULL,(int)NULL))== (int *)-1) {
        perror("shmat");    
        exit(1);  
      }
    Ensuite tu n'utilises que cette variable pour partager les données. Voici ton prog modifié, j'ai changé quelques vairables.
    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
     
    #include<stdio.h>
    #include <sys/ipc.h>
    #include<sys/types.h>
    #include<sys/shm.h>
    #define places_max 20
    #define cle (key_t) getuid()
    int places_reservees=0;
    int shmid;
    int *pt; // numero du segment de memoire
     
    void reservationPlaces(int nb)
    {
    /*   shmat(num, (const void *)addr, 0); */
     
      printf("nb places reservees %d \n", places_reservees);
      printf("Vous voulez reserver %d place(s)\n", nb);
      if(*pt+nb<=places_max)
        {
          places_reservees+=nb;
          printf("La reservation a ete faite.\n");
        }
      else
        {
          printf("La reservation ne peut pas se faire car on depasse le nombre maximum de places.\n");
        }
    }
     
    int main()
    {
      int n;                // variable qui contient le nombre de places qu'un processus veut reserver
      int pid;              // valeur de retour de la primitive fork
      int i, *pint;
      int *addr1, *addr2;
      struct shmid_ds *buf;
      buf=(struct shmid_ds *)malloc(sizeof(struct shmid_ds));
     
      printf("Voici le nombre de places disponibles actuellement : %d\n", places_max-places_reservees);
     
      // Allouer un segment de memoire partagee
      if((shmid = shmget(cle, 128*1024, IPC_EXCL|IPC_CREAT|0666)) == -1)
        {
          perror("Probleme de creation du segment de memoire\n");
          if (shmctl(shmid,IPC_RMID,buf) == -1)
    	{
    	  perror("Erreur de destruction du segment de memoire\n") ;
    	}
          exit(1);
        }
      else printf("Segment d'identificateur %d cree\n", shmid);
     
      if((pt=(int *)shmat(shmid,NULL,(int)NULL))== (int *)-1) {
        perror("shmat");    
        exit(1);  
      }
     
    /*   // Controler la memoire partage */
    /*   if(shmctl(num,IPC_STAT,buf)==-1) */
    /*     { */
    /*       perror("Probleme lors du controle du segment de memoire\n"); */
    /*       exit(2); */
    /*     } */
     
      // Creation du processus fils
      pid = fork();
     
      if(pid < 0) { // pb
        perror("Pb de creation du fils\n");
        exit(1);
      }
      if(pid == 0) { // fils
        n = 19;
        *pt = n;
        reservationPlaces(n);
     
        if(shmdt((const void *)pt)==-1) {
          perror("detachement impossible\n");
          exit(2);
        } 
      }else { // pere
        n = 8;
        *pt= n;
        reservationPlaces(n);
     
        if(shmdt((const void *)pt)==-1) {
          perror("detachement impossible\n");
          exit(4) ;
        }
      }
     
      // attendre la fin des processus
      while(wait(NULL)!=-1);
     
      printf("Voici le nombre de places disponibles actuellement : %d\n", places_max-places_reservees);
      exit(0);
     
     if (shmctl(shmid,IPC_RMID,buf) == -1)
       {
         perror("Erreur de destruction du segment de memoire\n") ;
         exit(5) ;
       }
     
      return 0;
    }

  5. #5
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    88
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 88
    Points : 59
    Points
    59
    Par défaut
    ok j'essaie ça dès que je relance ma petite kaella! je te tiens au courant d'ici demain soir, merci bcp bcp!!!

    Je retourne à mon lancer de rayons ;-)

    Bon week end!

    Ninie

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/01/2013, 11h46
  2. creation de segment memoire partagé
    Par marianna dans le forum Linux
    Réponses: 1
    Dernier message: 04/12/2007, 10h59
  3. probleme de segment de memoire partagé
    Par charisma dans le forum C
    Réponses: 1
    Dernier message: 09/01/2007, 10h08
  4. segment de memoire partagé en C
    Par thierry_b dans le forum C
    Réponses: 2
    Dernier message: 29/11/2005, 21h30
  5. Réponses: 13
    Dernier message: 05/05/2004, 19h09

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