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 :

Memoire partagée sous FreeBSD


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 277
    Par défaut Memoire partagée sous FreeBSD
    Bonjour,

    J'essaie de faire tourner un exemple trouvé sur le net de partage de mémoire entre 2 processus distinct (pas de thread) sous FreeBSD 7.1 avec kernel recompilé (j'ai supprimé tout ce qui ne servait pas pour moi). Voici le source du processus A qui écrit dans la structure partagée:

    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
    // code source du processus A
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <stdio.h>
     
    #define CLEF 12345 // je définis une clef au hasard
     
    // Je définis une structure quelconque qui comporte un entier et un double.
    typedef struct
    {
    	int a;
    	double b;
    }structure_partagee;
     
    int main()
    {
    	// variable quelconque qui me sers pour un compteur plus bas...
    	int i = 0;
     
    	int mem_ID; // identificateur du segment de mémoire partagée associé à CLEF
    	void* ptr_mem_partagee; // pointeur sur l'adresse d'attachement du segment de mémoire partagée
     
    	// J'instancie une structure "structure_partagee" et je l'appelle Data.
    	structure_partagee Data;
     
    	if ((mem_ID = shmget(CLEF, sizeof(Data), 0666 | IPC_CREAT)) < 0) // je crée un nouveau segment mémoire de taille "taille de ma structure data" octets, avec des droits d'écriture et de lecture
    	{
    		perror("shmget"); // et je m'assure que l'espace mémoire a été correctement créé
    		return(1);
    	}
     
    	if ((ptr_mem_partagee = shmat(mem_ID, NULL, 0)) == (void*) -1) // J'attache le segment de mémoire partagée identifié par mem_ID au segment de données du processus A dans une zone libre déterminée par le Système d'exploitation
    	{
    		perror("shmat"); // et je m'assure que le segment de mémoire a été correctement attaché à mon processus
    		return(1);
    	}
     
    	// J'alloue des valeurs aux variables de ma structure
    	Data.a = 2;
    	Data.b = 2.6544;
     
    	// je mets à jour ces valeurs en mémoire partagée. ptr_mem_partagee est un pointeur de void. Je le caste pour qu'il devienne un pointeur de "structure_partagee" Et je vais écrire ma structure Data à l'adresse pointée par ce pointeur.
    	*((structure_partagee*)ptr_mem_partagee) = Data;
     
    	// je vais modifier en permanence le champ a de ma structure et le mettre à jour, le processus B lira la structure Data.
    	while(1)
    	{
    		Data.a = i;
    		*((structure_partagee*)ptr_mem_partagee) = Data;
    		i++;
    		if(i == 100000000) // je remets à 0 de temps en temps...
    			i = 0;
    	}
     
    	// Une fois sortie de la boucle (bon OK là elle est infine), je détache mon segment mémoire de mon processus, et quand tous les processus en auront fait autant, ce segment mémoire sera détruit.
    	shmdt(ptr_mem_partagee);
    	return 0;
    }
    et le code du processus B qui va lire dans cette structure:

    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
    // code source du processus B
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <stdio.h>
     
    #define CLEF 12345 // !!je définis la même clef que celle du processus A!!
     
    // Je crée la même structure que dans le programme A.
    // Les noms des variables n'ont rien à voir avec le programme A, seule la structure est importante.
    typedef struct
    {
    	int c;
    	double d;
    }structure_partagee_B;
     
    int main()
    {
    	// je déclare des variables aptes à recevoir les variables de la structure "structure_partagee" définie dans le processus A
    	int var1;
    	double var2;
     
    	int mem_ID_B; // identificateur du segment de mémoire partagée associé à CLEF (là encore le nom de cette variable n'a rien à voir avec celle du programme A mais son contenu sera évidemment identique)
    	void* ptr_mem_partagee_B; // adresse d'attachement du segment de mémoire partagée (idem)
     
    	// J'instancie une structure "structure_partagee_B" et je l'appelle Data_B. Cela me sert uniquement à connaitre la taille de ma structure. Pour bien faire, il faudrait évidemment déclarer cette structure dans un .h qui serait inclu dans A et dans B avec la clef, de façon à garder la cohérence entre les 2 programmes
    	structure_partagee_B Data_B;
     
    	if ((mem_ID_B = shmget(CLEF, sizeof(Data_B), 0444)) < 0) // Je cherche le segment mémoire associé à CLEF et je récupère l'identificateur de ce segment mémoire... J'attribue des droits de lecture uniquement
    	{
    		perror("shmget"); // et je m'assure que l'espace mémoire a été correctement créé
    		return(1);
    	}
    	if ((ptr_mem_partagee_B = shmat(mem_ID_B, NULL, 0)) == (void*) -1) // J'attache le segment de mémoire partagée identifié par mem_ID_B au segment de données du processus B dans une zone libre déterminée par le Système d'exploitation
    	{
    		perror("shmat"); // et je m'assure que le segment de mémoire a été correctement attaché à mon processus
    		return(1);
    	}
     
    	printf ( "[processusB] OK\n" );	
    	// j'affiche le contenu des variables inscrites par A dans la mémoire partagée
    	while(1)
    	{
    		// je caste ptr_mem_partagee_B pour qu'il devienne un pointeur de structure_partagee_B et j'affiche le champ c (ou d) de la structure pointée par ((structure_partagee_B*)ptr_mem_partagee_B)
    		var1 = ((structure_partagee_B*)ptr_mem_partagee_B)->c;
    		var2 = ((structure_partagee_B*)ptr_mem_partagee_B)->d;
     
    		// j'affiche le contenu des champs de la structure l'un à côté de l'autre, et je reviens au début de la ligne.
    		printf ( "[processusB] %s\n", var1 );
    		printf ( "[processusB] %s\n", var2 );
    	}
     
    	// Je détruis le segment (le segment n'est pas détruit tant qu'au moins un processus est lié au segment)
    	shmdt(ptr_mem_partagee_B);
    	return 0;
    }
    Je compile par:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    gcc a.c -o c
    gcc b.c -o b
    Pas de problème, je lance A:

    Pas de problème, je lance B:

    et la j'ai une segmentation fault à la ligne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var1 = ((structure_partagee_B*)ptr_mem_partagee_B)->c;
    D'où peut venir le problème ? La façon de partager une portion de mémoire diffère-t-elle de Linux à FreeBSD ?

    Cordialement.

  2. #2
    Expert confirmé

    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 : 44
    Localisation : Etats-Unis

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Ceci pourrait te poser des problèmes :
    exb.c: In function ‘main’:
    exb.c:49: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
    exb.c:50: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘double’
    Jc

  3. #3
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 277
    Par défaut Quel OS ?
    Bonjour,

    gcc sous FreeBSD 7.1 ne donne aucun message de warning, sous quel OS as-tu compilé ?

    Cordialement.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    gcc avec quelles options* sous FreeBSD 7.1, et quelle version de gcc?

    *J'ai appris à mes dépens que gcc en ligne de commande n'affichait pas de warnings à moins qu'on les lui demande explicitement.
    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.

  5. #5
    Expert confirmé

    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 : 44
    Localisation : Etats-Unis

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par Lovmy Voir le message
    Bonjour,

    gcc sous FreeBSD 7.1 ne donne aucun message de warning, sous quel OS as-tu compilé ?

    Cordialement.
    Ubuntu:
    Linux 2.6.27-14-generic #1 SMP Tue Aug 18 16:25:45 UTC 2009 i686 GNU/Linux


    Using built-in specs.
    Target: i486-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.3.2-1ubuntu12' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
    Thread model: posix
    gcc version 4.3.2 (Ubuntu 4.3.2-1ubuntu12)

    *J'ai appris à mes dépens que gcc en ligne de commande n'affichait pas de warnings à moins qu'on les lui demande explicitement.
    Compilé sans options d'ailleurs ;-)
    Jc

  6. #6
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 277
    Par défaut Ca marche
    Bonjour,

    OK ça marche, merci !

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

Discussions similaires

  1. Boot réseau sous FreeBSD
    Par black is beautiful dans le forum Réseau
    Réponses: 6
    Dernier message: 24/04/2005, 18h23
  2. Utilisation de la librairie ng sous FreeBSD
    Par Mercenary Developer dans le forum Autres éditeurs
    Réponses: 3
    Dernier message: 07/12/2004, 09h39
  3. [Free Pascal] Pascal sous FreeBSD
    Par logiqueciel dans le forum Free Pascal
    Réponses: 5
    Dernier message: 23/09/2004, 20h06
  4. Réponses: 13
    Dernier message: 05/05/2004, 19h09
  5. [FreeBSD] Passer root sous FreeBSD
    Par Willand dans le forum BSD
    Réponses: 3
    Dernier message: 15/04/2004, 09h54

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