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 mémoire partagé


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2010
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Avril 2010
    Messages : 25
    Par défaut Segment de mémoire partagé
    Bonjour,

    J'ai besoin de faire un segment de mémoire partagé dans un programme en C sous Linux.

    Je pense que je l'attache mal parce que ça compile mais quand je l'utilise toutes les données sont à 0.

    Variables globales :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int shmid;
    nat * tab_nat;
    nat est une structure, initialisé correctement dans le main.
    tab_nat est un tableau de ces structures également bien initialisé.

    Voici la déclaration du shm dans le main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if ( (shmid = shmget(CLE_IPC, sizeof(tab_nat), 0666 | IPC_CREAT)) < 0 ) {
     
    		perror("shmget");
    		return EXIT_FAILURE;
     
    }
    Et l'utilisation dans une fonction (qui devra être appellé par un processus) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	nat * ptr;	
     
    	ptr = shmat(shmid, NULL, 0);
     
    	printf("%x\n",ptr[0].adr_pub);
    	printf("%x\n",tab_nat[0].adr_pub);
    Le premier printf affiche 0 alors que le se second affiche bien la bonne valeur... La lecture via le segment de mémoire partagée ne semble donc pas marcher.

    Quelqu'un aurait il une idée d'où peut provenir mon erreur ?

    Merci d'avance,

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    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 442
    Par défaut
    Tu nous donnes trop peu d'informations pour que l'on puisse te répondre. Il nous faudrait le code entier, s'il est raisonnablement long. On ne sait pas quand les processus sont créés, etc.

    Quoiqu'il en soit, il n'y a rien qui nous laisse à penser que « tab_nat » est initialisé avec le retour de shmat(). Si c'est une structure que tu as créée avant de forker, alors ton nouveau processus en a hérité d'une copie, mais les deux instances restent indépendantes.

    D'autre part, dans :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    shmid = shmget(CLE_IPC, sizeof(tab_nat), 0666 | IPC_CREAT)

    • tab_nat est un pointeur. Pas un tableau déclaré comme tel. La taille de ton segment partagé sera donc celle d'un pointeur (quatre octets), et pas celle d'une structure « nat » ;
    • shmget() va, ici, créer un segment de mémoire partagée, qui pourra ensuite être rattaché sur demande à un ou plusieurs processus. Il s'agit d'allocation de mémoire comme le fait malloc(). En aucun cas tu ne vas partager la structure existante pointée par tab_nat.

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2010
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Avril 2010
    Messages : 25
    Par défaut
    Bonjour,

    Merci de me donner un coup de main.

    Pour le moment je n'ai démarré aucun processus. Je fais des tests avec les fonctions du programmes principales. Voici ce que je chercher à réaliser :
    1. Dans le programme principale tab_nat est initilialisée de manière classique.
    2. Je créer le segment de mémoire partage pour partager tab_nat.
    3. Je fork deux fois, chaque processus fils appelle une fonction
    4. Dans ces fonctions, j'accèderai au segment de mémoire partagé.
    Donc voilà je ne sais pas si c'est la bonne méthode mais ça me parait logique. J'ai vu sur le net qu'on pouvait d'abord créer le shm et l'initialisé dans le main à partir du pointeur de shm mais je ne pense pas qu'il y ait de grande différence. Après j'aurais surement à ajouter une synchonisation par sémaphore vu que les fonctions font de la lecture/écriture.

    En tout cas mon but est bien de partager le tableau tab_nat, et pas 4 octets
    Comment faire le shmget dans ce cas là ?


    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
    	
    
    struct s_nat {
    
    	struct in_addr adr_priv;
    
    	struct in_addr adr_pub;
    
    	time_t 	 start;
    
    };
    
    typedef struct s_nat nat;
    
    [...]
    
    tab_nat = (nat *) malloc(n * sizeof(nat));
    
    	int shm_size = sizeof(nat) * n;
    
    	if ( (shmid = shmget(CLE_IPC, shm_size, 0666 | IPC_CREAT)) < 0 ) {
    
    		perror("shmget");
    
    		return EXIT_FAILURE;
    
    	}
    
    
    	shmptr = shmat (shmid,NULL,SHM_R | SHM_W);
    	
    	if (shmptr == NULL) {
    		perror("shmat");
    		exit(EXIT_FAILURE);
        }
    	printf("ok !\n");
    	shmptr[0]->start = (time_t) 0; //  <-- SEG FAULT
    	printf("ok !\n");
    	//printf(" %l ", shmptr[0]->adr_pub.s_addr);
    	return 1;
    
    	/*

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

    Citation Envoyé par dedibox26 Voir le message
    Voici ce que je chercher à réaliser :
    1. Dans le programme principale tab_nat est initilialisée de manière classique.
    2. Je créer le segment de mémoire partage pour partager tab_nat.
    La réponse est dans mon post précédent. Relis-le bien.

    On ne déclare pas une structure pour la partager a posteriori. shmget() permet de récupérer un segment de mémoire partagée déjà existant, ou de le créer s'il n'existe pas. Comme un fichier.

    En ce sens, déclarer un segment de mémoire partagée est tout-à-fait comparable à de l'allocation de mémoire avec malloc().

    Ce qu'il faut donc faire, c'est placer la ligne suivante :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    tab_nat = (nat *) malloc(n * sizeof(nat));

    après shmget() et remplacer malloc() par shmat() telle que tu l'utilises un peu plus bas.

Discussions similaires

  1. Allocation dans un segment de mémoire partagé
    Par Malek_moly dans le forum C
    Réponses: 7
    Dernier message: 23/04/2012, 20h24
  2. Segmentation fault dans un contexte de mémoire partagée
    Par introdisco dans le forum Débuter
    Réponses: 2
    Dernier message: 05/02/2012, 20h48
  3. Segment de mémoire partagée POSIX, socket et select
    Par Antoine J. dans le forum POSIX
    Réponses: 2
    Dernier message: 06/12/2011, 16h42
  4. [SHM] shmget crée uniquement des segments de mémoire partagée privée
    Par prgasp77 dans le forum Administration système
    Réponses: 1
    Dernier message: 23/09/2009, 08h20
  5. [IPC] libération segment mémoire partagée
    Par joyled dans le forum Linux
    Réponses: 10
    Dernier message: 31/12/2008, 00h51

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