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 :

Utilisation de la memoire partage


Sujet :

C

  1. #1
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    271
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 271
    Points : 91
    Points
    91
    Par défaut Utilisation de la memoire partage
    Bonjour,

    J ai un programme qui fait plusieurs fils et j aimerais que chacun des fils puisse modifier la valeur de plusieurs variables.

    J ai d abord pense ( naivement) a declarer mes variables en globale. Mais bien sur chaque variable est recopie dans chacun des processus et ne designe donc pas les memes adresse memoires...

    Je pense que la seule solution est de creer un segment de memoire partage. Mais des utilisations que j ai pu en voir, on ne peut mettre qu une valeur dans un segment et cela m obligerai a declarer pas mal de segments...

    Est ce que vous connaissez un moyen de mettre plusieurs valeurs ds un segment de memoire partage et de pouvoir recuperer (ou modifier) une valeur precise ?

    Merci d avance !

    (Si vous avez une autre solution a mon probleme je suis preneur aussi...)

  2. #2
    Expert éminent sénior
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Points : 13 380
    Points
    13 380
    Par défaut
    Et pourquoi pas projeter une structure en mémoire?
    Introduction à Silverlight 4 (new) ; Localisation d'une application Silverlight (new) ;
    Mon espace perso[/B]

    La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Albert Einstein[/SIZE]

  3. #3
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    La mémoire partagée est une zone mémoire donc tu as autant de place que le système veut bien te donner. Ce que tu fais de cette zone est ensuite à toi de voir.

    Tu pourras y mettre un tableau, une liste chaînée, etc...

    Jc

  4. #4
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    271
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 271
    Points : 91
    Points
    91
    Par défaut
    Ah oui c bien ca !

    Mais ca donnerait quoi ? ca ? :
    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
     
     
    typedef struct mastruct{
                                      int argument1;
                                      int argument2;
                                      int argument3;
                                    }
    main(){
     
    int shmid ; // l'identificateur de la memoire partagee 
    key_t clef ; // la clef associee au segment
    char* mem;
    struct mastruct mesarg;
     
    mesarg.argument1 = 1;
    mesarg.argument2 = 2;
    mesarg.argument3 = 3;
     
     
    clef = ftok(name,(key_t) cle) ;
     
    shmid = shmget(clef,sizeof(mastruct),IPC_CREAT|IPC_EXCL|SHM_R|SHM_W ) ;
     
    if ( shmid== -1 ) {
        perror("La creation du segment de memoire partage a echouee") ;
        exit(1) ;}
     
    switch(fork){
     
           case 0 :  
                      mem = shmat(shmid,0,flag);
                      *mem = mesarg; //????????????
     
                            ...
    Et pour recuperer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    processus b(){
     
            char* mem;
            struct mastruct mesarg2;
     
            mem = shmat(shmid,0,flag);
            mesarg2 = *mem;// ?????
                   ...
    Je sens bien que ca va pas etre aussi simple ...

  5. #5
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par Treuze
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    processus b(){
     
            char* mem;
            struct mastruct mesarg2;
     
            mem = shmat(shmid,0,flag);
            mesarg2 = *mem;// ?????
                   ...
    Pourquoi utiliser un char * ?
    Tu peux directement faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    processus b ()
    {
      struct mastruct mesarg2;
     
      mesarg2 = shmat(shmid,0,flag);
    }
    man shmget
    man shmat

  6. #6
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    271
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 271
    Points : 91
    Points
    91
    Par défaut
    Tiens ... sur linux-kheops , il renvoie un char* ...

    Bien le merci ! je vais essayer ts ca

  7. #7
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    271
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 271
    Points : 91
    Points
    91
    Par défaut
    Pourquoi utiliser un char * ?
    Tu peux directement faire :
    Code :
    processus b ()
    {
    struct mastruct mesarg2;

    mesarg2 = shmat(shmid,0,flag);
    }

    incompatible types inassignement

    C est bien un char* qui est renoye , il va falloir revoir le man du site ...

  8. #8
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    271
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 271
    Points : 91
    Points
    91
    Par défaut
    Non vraiment je en vois pas comment recuperer la structure en memoire ...

    Je ne peux pas faire un etat = *mem , les types sont differents....

    Comment est ce que je peut recuperer le contenu de la memoire pointe par l adresse mem ?

  9. #9
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par Treuze
    C est bien un char* qui est renoye , il va falloir revoir le man du site ...
    Et les sources de FreeBSD : Source to sys/shm.h

    P.S. : et les pages man du sites sont très bien
    SVr4, SVID. SVr4 mentionne une condition d'erreur supplémentaire EMFILE. Dans SVID-v4 le type de l'argument shmaddr a été modifié de char * en const void *, et le type de retour de shmat() de char * en void *. (Les bibliothèques Linux libc4 et libc5 avaient le prototype char * , la GlibC 2 celui void *).

  10. #10
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Par contre ce qui est vrai, c'est qu'il faudrait mieux avoir un pointeur pour récupérer la valeur...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    processus b ()
    {
      struct mastruct *mesarg2;
     
      mesarg2 = shmat(shmid,0,flag);
    }
    Jc

  11. #11
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    271
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 271
    Points : 91
    Points
    91
    Par défaut
    Merci a tous !

    Alors pour ceux que ca pourrait aider, voila comment mettre une structure en memoire partage (ss verification des code de retours...) :

    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
     
    typedef struct mastructure{<div style="margin-left:40px">int argument1;
    int argument2;
    }
    </div>int mem_id;
     
    main(){<div style="margin-left:40px">struct mastructure *memoire;
     
    mem_id = shmget(NULL,sizeof(structmastructure),IPC_CREAT|IPC_EXCL)
     
    memoire = shmat(mem_id,0,0);
     
    *memoire = malloc (sizeof(struct mastructure));
    memoire->argument1 = 0;
    memoire->argument2 = 0;</div>swith(fork){
    <div style="margin-left:40px"><div style="margin-left:40px">case 0 :<div style="margin-left:40px">struct mastructure *etat;
     
    etat = shmat(mem_id,0,0);
    //etat pointe sur le segment de memoire partage
     
    ...
    </div></div></div>
    Volia si vous avez des remarques , je prends !
    P.S. : et les pages man du sites sont très bien
    C est a linux-kheops que je vais ecrire ...

  12. #12
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par Treuze
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mem_id = shmget(NULL,sizeof(structmastructure),IPC_CREAT|IPC_EXCL)
    Si j'ai bien tout suivi, le premier argument de la fonction shmget doit être une clé (de type key_t) unique pour chaque ressource demandée (mémoire partagée, sémaphore...). Voic un code avec la gestion des erreurs :
    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
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/shm.h>
    #include <sys/wait.h>
     
    typedef struct
    {
      int nb;
      const char *msg;
    } shared_s;
     
    int main (int argc, char **argv)
    {
      int id;
      int pid;
      shared_s *s = NULL;
      key_t cle;
     
      errno = 0;
      cle = ftok (argv[0], 'a');
      if (cle != -1)
      {
        errno = 0;
        id = shmget (cle, sizeof (shared_s), IPC_CREAT | 0666);
        if (id != -1)
        {
          errno = 0;
          s = shmat (id, NULL, 0);
          if (s != (void *)-1)
          {
            s->nb = 2;
            s->msg = "Shared hello world";
     
            errno = 0;
            pid = fork ();
            if (pid > 0)
            {
              /* Processus pere */
              int i;
     
              for (i = 0; i < s->nb; i++)
              {
                printf ("%s\n", s->msg);
              }
              waitpid (pid, NULL, 0);
              for (i = 0; i < s->nb; i++)
              {
                printf ("%s\n", s->msg);
              }
            }
            else if (pid == 0)
            {
              /* Processus fils */
              shared_s *ss = NULL;
     
              /*
               * On laisse le temps au processus pere d'afficher le message
               * d'origine.
               */
              sleep (1);
              ss = shmat (id, NULL, 0);
              if (ss != (void *)-1)
              {
                ss->nb = 5;
                ss->msg = "Msg modifier !";
              }
              else
              {
                perror ("shmat");
                return EXIT_FAILURE;
              }
            }
            else
            {
              perror ("fork");
              return EXIT_FAILURE;
            }
          }
          else
          {
            perror ("shmat");
            return EXIT_FAILURE;
          }
        }
        else
        {
          perror ("shmget");
          return EXIT_FAILURE;
        }
      }
      else
      {
        perror ("ftok");
        return EXIT_FAILURE;
      }
     
      (void)argc;
      return EXIT_SUCCESS;
    }
    Plutôt qu'un sleep il faudrait mieux créer un sémaphore au niveau du processus père.

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

Discussions similaires

  1. Detacher la memoire partage
    Par Treuze dans le forum C
    Réponses: 3
    Dernier message: 19/06/2006, 17h34
  2. Probleme avec memoire partage
    Par Treuze dans le forum C
    Réponses: 3
    Dernier message: 12/06/2006, 13h32
  3. segment de memoire partagé en C
    Par thierry_b dans le forum C
    Réponses: 2
    Dernier message: 29/11/2005, 21h30
  4. [segment de memoire partagée]
    Par pitit777 dans le forum C
    Réponses: 4
    Dernier message: 26/11/2005, 14h47
  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