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 :

Fonction mmap et argument prot


Sujet :

Linux

  1. #1
    Membre à l'essai
    Inscrit en
    Janvier 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations forums :
    Inscription : Janvier 2009
    Messages : 11
    Points : 12
    Points
    12
    Par défaut Fonction mmap et argument prot
    Bonjour,

    j'utilise la fonction mmap pour partagé un espace mémoire entre deux processus (l'un père et l'autre son fils).
    void *mmap(void *start, size_t length, int prot,int flags , int fd, off_t offset);
    Cependant, j'ai une question sur la description de l'argument prot dans les pages du manuel version 1.6f :
    "Il s'agit soit de PROT_NONE (le contenu de la mémoire est inaccessible) soit d'un OU binaire entre les constantes suivantes" : PROT_EXEC, PROT_READ, PROT_WRITE, PROT_NONE.

    Or dans mon programme, j'ai besoin de lire et d'écrire dans la zone partagée.
    En utilisant PROT_READ || PROT_WRITE j'ai une erreur de segmentation (139) en écrivant dans la zone.
    Alors qu'en utilisant le drapeau PROT_WRITE seul, les lectures et écritures se font correctement. Pourtant selon le manuel je devrais utiliser les deux drapeaux avec un OU non ?

    Voici mon code pour ceux qui voudraient y jeter un coup d'oeil au cas où le dysfonctionnement viendrai de celui-ci
    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
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    /*
     * Calcul d'une somme de matrice dans un espace
     * mémoire partagé par deux processus.
    */
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
     
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <sys/mman.h>
    #include <sys/wait.h>
     
    /*****************************
     * (DÉBUT) MATRICE
    *****************************/
     
    #define TAILLE 4
     
    /* Structure représentant une matrice carrée */
    typedef struct mat Mat;
    struct mat {
      int taille;
      int t[TAILLE][TAILLE];
    };
     
    void remplirMat(Mat* m) {
      int i,j,cpt=0;
      m->taille = TAILLE;
      for (i=0; i<m->taille; i++)
        for (j=0; j<m->taille; j++) {
          m->t[i][j] = cpt;
          cpt++;
        }
    }
     
    void affichMat(Mat* m) {
      int i,j;
      for (i=0; i<m->taille; i++) {
        for (j=0; j<m->taille; j++)
          printf("%d\t", m->t[i][j]);
        printf("\n");
      }
    }
     
    /****************************
     * (FIN) MATRICE
    ****************************/
     
    /* Structure de la mémoire partagée */
    typedef struct mem Mem;
    struct mem {
      Mat matSom;  /* Matrice résultant de la somme */
    };
     
    int main(int argc, char** argv) {
     
      int i,j;
      pid_t pidFils;  /* PID du processus fils */
      int dsc;	  /* Descripteur du fichier */
      Mem *obj;	  /* Zone mémoire partagée entre les proc. */
      Mat mat1, mat2;  /* Deux matrices */
     
      errno = 0;
      /* ouvre un fichier (qui sera projeté en mémoire) */
      dsc = open("/home/guillaume/bidon", O_RDWR);
      if (dsc == -1) {
        perror("main l.27");
        return -1;
      }
      else {
     
        errno = 0;
        /* réajuste la taille du fichier à celle nécessaire */
        if (ftruncate(dsc, sizeof(Mem)) == -1) {
          perror("main l.38");
          return -1;
        }
        else {
     
          errno = 0;
          /* projete le fichier en mémoire */
          obj = (Mem*) mmap(0, sizeof(Mem), PROT_WRITE, MAP_SHARED,
    						  dsc, 0);
          if (obj == (void*) -1) {
    	perror("main l.43");
    	return -1;
          }
          else {
     
    	remplirMat(&mat1); /* initialisation et affichage des */
    	remplirMat(&mat2); /* matrices */
    	affichMat(&mat1); printf("\n");
    	affichMat(&mat2);
    	remplirMat(&(obj->matSom)); /* écrase les anciennes données */
     
    	pidFils = fork(); /* Lance le processus fils */
    	if (pidFils == -1)
    	return -1;
    	else if (pidFils == 0) { /* Processus fils */
     
    	  for (i=0; i<obj->matSom.taille; i++)	// Ttes les lignes
    	    for (j=1; j<obj->matSom.taille; j+=2) // Ttles les colonnes impaires
    	      obj->matSom.t[i][j] = (mat1.t[i][j] + mat2.t[i][j]); // Somme des 2 matrices
     
    	  exit(0); // Processus terminé
    	}
    	else { /* Processus père */
     
    	  for (i=0; i<obj->matSom.taille; i++)	// Ttes les lignes
    	    for (j=0; j<obj->matSom.taille; j+=2) // Ttles les colonnes paires
    	      obj->matSom.t[i][j] = (mat1.t[i][j] + mat2.t[i][j]); // Somme des 2 matrices
     
    	  wait(NULL); // Attend que le proc. fils est terminé
    	}
     
    	printf("Somme des matrices : \n");
    	affichMat(&(obj->matSom));
     
    	if (munmap(obj, sizeof(Mem)) != 0) return -1; /* supprime la projection en mémoire */
    	if (close(dsc) != 0) return -1; /* ferme le fichier */
     
          }
        }
      }
     
      return 0;
    }
    Merci de m'éclaircir.

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 043
    Points
    31 043
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par S. Guillaume Voir le message
    "Il s'agit soit de PROT_NONE (le contenu de la mémoire est inaccessible) soit d'un OU binaire entre les constantes suivantes" : PROT_EXEC, PROT_READ, PROT_WRITE, PROT_NONE.

    Or dans mon programme, j'ai besoin de lire et d'écrire dans la zone partagée.
    En utilisant PROT_READ || PROT_WRITE j'ai une erreur de segmentation (139) en écrivant dans la zone.
    Alors qu'en utilisant le drapeau PROT_WRITE seul, les lectures et écritures se font correctement. Pourtant selon le manuel je devrais utiliser les deux drapeaux avec un OU non ?
    On te parle d'un "ou binaire"... et t'as mis un "ou logique"

    Le "ou logique" s'applique au booléen vrai/faux: vrai ou faux = vrai

    Le "ou binaire" est un "ou" qui s'applique pour chaque bit de l'opérande n° 1 situé à la même place que le bit de l'opérande n° 2.
    Ex: 5 | 6 = 101 | 110 = 111 = 7.
    C'est aussi le principe du chmod. Quand on écrit r+x = 4 + 1 = 5, c'est pas tout à fait l'opération exacte.
    Ce qui se passe, c'est qu'on associe le flag "r" 100 avec le flag "x" 001 via un "ou binaire" ce qui donne 100 | 001 = 101
    Dans ce cas là, comme chaque flag correspond à une puissance de 2, c'est la même chose qu'une addition mais pour le puriste ce n'est pas une addition.

    Ce principe de "ou binaire" sur les paramètres de fonctions sont très utilisés. Ca permet de mettre en une seule variable tout un tas de flags qui, sans cette possibilité, auraient nécessité un tas de paramètres.

    Dans ton cas, te faut mettre PROT_READ | PROT_WRITE

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

Discussions similaires

  1. fonction callback avec arguments
    Par YuGiOhJCJ dans le forum GTK+ avec C & C++
    Réponses: 12
    Dernier message: 12/04/2013, 08h42
  2. Réponses: 14
    Dernier message: 16/05/2006, 11h26
  3. Fonction callback avec arguments ?
    Par sorry60 dans le forum GTK+ avec C & C++
    Réponses: 39
    Dernier message: 07/11/2005, 10h41
  4. fonction unserialize et argument
    Par Ti Jen-tsie dans le forum Langage
    Réponses: 1
    Dernier message: 29/10/2005, 20h08
  5. fonction dont les argument sont dans un dico
    Par GConstant dans le forum Général Python
    Réponses: 1
    Dernier message: 12/08/2004, 18h24

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