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 :

Utilisation simple d'une mémoire partagée sous linux


Sujet :

Linux

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Février 2007
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Utilisation simple d'une mémoire partagée sous linux
    Bonjour,

    Je suis bloqué par un problème. Je travaille sous linux. J'ai 2 processus (au sens de 2 exécutables (pas de rapport de filiation comme pour les

    threads)).
    Le premier processus (A) produit des données sous forme de structure.
    Le second processus (B) doit lire les données produites par A de temps à autre (A et B sont asynchrones). Il existe plusieurs moyens de faire

    communiquer des processus entre eux, et parmi ceux là, la mémoire partagée me semble être l'idéal (contrainte temps réel et la mémoire partagée est ce

    qu'il y a de plus rapide pour faire transiter les données).
    J'ai lu énormément de documentation sur internet, mais les exemples concrets sont rares. Les 2 programmes que j'essaie de construire ne fonctionnent pas

    et j'aurais aimé un coup de main pour m'en sortir...
    Voici le source de mes programmes.


    Programme A
    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
     
    //	code source du processus A
    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
     
    #define CLEF 12345 // je définis une clef au hasard
     
    int main()
    {
    	//	Je crée une structure quelconque qui comporte un entier et un double.
    	typedef struct
    	{
    		int a;
    		double b;
    	}structure_partagee;
     
    	//	J'instancie une structure "structure_partagee" et je l'appelle data.
    	structure_partagee data;
     
    	int mem_ID; //	identificateur du segment de mémoire partagée associé à CLEF
    	void* ptr_mem_partagee; //	adresse d'attachement du segment de mémoire partagée
     
    	mem_ID = shmget(CLEF, sizeof(data), 0666 | IPC_CREAT);	//	je crée un nouveau segment mémoire de taille "taille de ma structure data" 
     
    octets, avec des droits d'écriture et de lecture
    	ptr_mem_partagee = shmat(mem_ID, NULL, 0);	//	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
     
    	//	J'alloue des valeurs aux variables de ma structure
    	data.a = 3;
    	data.b = 2.5666;
     
    	//	et j'attends que le programme B vienne lire ces valeurs
    	getchar();
     
    	//	Lorsqu'une touche est frappée, 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);
     
    	//	je quitte le programme
    	return 0;
    }
    Alors pour commencer, ce programme est correctement compilé (avec gcc A.cpp -o A) SI je ne mets pas getchar()... Sinon, j'ai une vilaine erreur que je

    ne comprends pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    /tmp/ccwmOC2V.o:(.eh_frame+0x11): référence indéfinie vers « __gxx_personality_v0 »
    collect2: ld returned 1 exit status
    Maintenant le programme B:
    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
     
    //	code source du processus B
    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <iostream>
     
    #define CLEF 12345 // je définis la même clef que celle du processus A
     
    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; //	identificateur du segment de mémoire partagée associé à CLEF
    	void* ptr_mem_partagee; //	adresse d'attachement du segment de mémoire partagée
     
    	//	ALORS LA JE SUIS PERDU...
    	mem_ID = shmget(CLEF, ?, ?);	//	Je suis sensé cherché le segment mémoire associé à CLEF et récupérer l'identificateur de ce segment 
     
    mémoire...
    	ptr_mem_partagee = shmat(mem_ID, NULL, 0);	//	J'attache le segment de mémoire partagée identifié par mem_ID au segment de données du 
     
    processus B dans une zone libre déterminée par le Système d'exploitation
     
    	var1 = data.a;
    	var2 = data.b;
     
    	//	j'affiche le contenu des variables, ce qui est censé me montrer que mon programme à fonctionner...
    	cout << "data.a = " << var1 << endl;
    	cout << "data.b = " << var2 << endl;
     
    	//	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);
     
    	//	je me mets en attente
    	getchar();
     
    	//	je quitte le programme
    	return 0;
    }
    Alors lui il ne compile forcemment pas puisqu'il y a des ? quand je fais le shmget...

    Est ce que je m'y prends de la bonne façon (ça m'étonnerait lol), et si ce n'est pas le cas, est ce que quelqu'un peut m'aider ?
    Merci d'avance...

  2. #2
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Février 2007
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Bon en fait j'ai résolu tout seul mon problème...
    Je poste le code ici, car je pense que cela pourra en aider certains...

    code source du programme A
    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
     
    //	code source du processus A
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <math.h>
    #include <iostream>
    using namespace std;
     
    #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éé
    		exit(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
    		exit(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);
     
    	//	je quitte le programme
    	return 0;
    }
    code source du programme B
    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
     
    //	code source du processus B
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <iostream>
    using namespace std;
     
    #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éé
    		exit(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
    		exit(1);
    	}
     
    	//	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.
    		cout << "data.a = " << var1 ;
    		cout << " data.b = " << var2 << "\r";
    	}
     
    	//	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);
     
    	//	je quitte le programme
    	return 0;
    }
    Voilà j'ai hyper commenté mes sources, mes en cas de pb n'hésitez pas, je pourrai peut-être vous aider.
    @+

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

Discussions similaires

  1. partage d'une bande passante sous linux
    Par PrettyMan dans le forum Réseau
    Réponses: 4
    Dernier message: 19/09/2012, 14h36
  2. Comment utiliser une librarie .so (sous linux)
    Par philipina dans le forum Linux
    Réponses: 14
    Dernier message: 20/02/2007, 13h05
  3. Peut-on utiliser une appllication .Net sous Linux ?
    Par goof_22 dans le forum Framework .NET
    Réponses: 8
    Dernier message: 18/10/2006, 11h08
  4. Sauvegarde efficace d'une base MySql sous Linux
    Par Arioch dans le forum Administration
    Réponses: 9
    Dernier message: 19/09/2004, 10h24
  5. Je ne peux établir une connexion cliente sous Linux.
    Par Anonymous dans le forum CORBA
    Réponses: 5
    Dernier message: 16/04/2002, 15h57

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