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:
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.