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 :

Mémoire commune entre deux processus - shmat


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 11
    Points : 8
    Points
    8
    Par défaut Mémoire commune entre deux processus - shmat
    Bnojour à tous,

    J'aurais besoin de votre aide pour un petit bout de code.
    J'ai un programme qui va créer plusieurs fils, et les gérer via des sémaphores et autres joyeusetés. Ce programme a donc besoin d'allouer de la mémoire commune pour que les processus puissent communiquer.

    Pour l'allocation, j'utilise le code ci-dessous :
    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
     
    	int* data;
    	int* nb_lus;
     
    	key = ftok(CLE,'R');
    	if(key == (key_t)-1){
    		perror("ftok:key");
    		exit(1);
    	}
     
    	shmid = shmget(key, 1024, 0666 | IPC_CREAT);
     
    	// Même chose pour le nombre de processus ayant lu les données
    	nb_lus = shmat(shmid, (char*)0, 0);
    	if(nb_lus == (int*)(-1)){
    		perror("shmot:nb_lus");
    		exit(1);
    	}
     
    	data = shmat(shmid, (char*)0, 0);
    	if(data == (int*)(-1)){
    		perror("shmot:data");
    		exit(1);
    	}
     
    	*data = 1;
    	*nb_lus = 2;
     
    	printf("Init::%d,%d\n",*nb_lus,*data);
    J'ai donc deux pointeurs qui sont récupérés via shmat, auxquels je donne des valeurs différentes, et j'en affiche la valeur à la fin.

    Le problème, c'est que la sortie est la suivante :Conclusion: shmat m'a renvoyé deux fois le même pointeur.

    Pouvez-vous m'aider à faire en sorte que shmat alloue deux segments de mémoire différents ? 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 372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    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 372
    Points : 23 628
    Points
    23 628
    Par défaut
    Bonjour,

    shmget (SHared Memory GET) sert à récupérer un segment de mémoire existant à l'aide de son identifiant et/ou le créer éventuellement s'il n'existe pas encore ;
    shmat (SHared Memory Attach) sert à attacher ce segment de mémoire dans l'espace d'adressage de ton processus pour pouvoir l'exploiter et écrire dedans.

    Si tu attaches deux fois le même segment, il est normal que tu obtiennes le même pointeur. Si tu veux obtenir deux segments de mémoire différents, il faut appeler deux fois shmget().

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Dans ce cas je dois créer une deuxième clé obligatoirement ? C'est un peu contraignant puisque les clés sont associées chacune à un fichier.

    Merci pour ta réponse en tout cas.

    EDIT : après une petite minute de réflexion, j'ai pu obtenir ceci :
    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
    	// Initialisation de la mémoire partagée
    	key = ftok(CLE,'W');
    	if(key == (key_t)-1){
    		perror("ftok:key");
    		exit(1);
    	}
     
    	// Création d'un segment de mémoire partagée	
    	shmid = shmget(key, 2*sizeof(int)+sizeof(sem_t), 0666 | IPC_CREAT);
     
    	// Attachement du segment de mémoire obtenu au processus
    	segment = shmat(shmid, (void*)0, 0);
    	if(segment == (void*)(-1)){
    		perror("shmat");
    		exit(1);
    	}
     
    	// Affectation des pointeurs aux bons emplacements du segment
    	data = segment;
    	nb_lus = segment + sizeof(int);
    	semaphore_lecture = (sem_t*)(nb_lus + sizeof(int));
    	semaphore_ecriture = semaphore_lecture + sizeof(sem_t);
     
    	// Test
    	*data = 1;
    	*nb_lus = 2;	
    	printf("Init::%d,%d\n",*nb_lus,*data);
    J'attache donc un segment et je positionne mes pointeurs aux bons endroits dessus. Est-ce la bonne méthode ?

  4. #4
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Bonjour,
    Je ne saurais te dire si cette méthode est bonne ou non, mais je peux pointer une erreur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	// Création d'un segment de mémoire partagée	
    	shmid = shmget(key, 2*sizeof(int)+sizeof(sem_t), 0666 | IPC_CREAT);
    Là tu réserves de la place pour deux int et un sem_t.
    Tu voulais peut-être plutôt écrire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	// Création d'un segment de mémoire partagée	
    	shmid = shmget(key, 2*(sizeof(int)+sizeof(sem_t)), 0666 | IPC_CREAT);

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Exact merci

    Par contre j'ai un nouveau problème : j'ai besoin de 3 sémaphores communes, et je tente donc de réserver le segment mémoire ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    shmid = shmget(key, 3*sizeof(sem_t), 0666 | IPC_CREAT);
    	if(shmid == -1){
    		perror("shmget");
    		exit(1);
    	}
    Et j'obtiens la sortie suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     shmget: Invalid argument
    Sachant qu'avec deux sémaphores seulement, ça fonctionne parfaitement bien.
    J'ai vérifié la taille de 3 sémaphores, et je tombe sur 48 octets, ce qui est peut puisque la taille maximale est de 4 Mo.

    Quelqu'un aurait une idée de solution ?

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par KaNaRette Voir le message
    Exact merci

    Par contre j'ai un nouveau problème : j'ai besoin de 3 sémaphores communes, et je tente donc de réserver le segment mémoire ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    shmid = shmget(key, 3*sizeof(sem_t), 0666 | IPC_CREAT);
    	if(shmid == -1){
    		perror("shmget");
    		exit(1);
    	}
    Et j'obtiens la sortie suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     shmget: Invalid argument
    Sachant qu'avec deux sémaphores seulement, ça fonctionne parfaitement bien.
    J'ai vérifié la taille de 3 sémaphores, et je tombe sur 48 octets, ce qui est peut puisque la taille maximale est de 4 Mo.

    Quelqu'un aurait une idée de solution ?
    Salut

    Si tu veux 3 sémaphores, inutile de passer par shmget(). Te suffit de les réserver via semget(key, 3, 0666 | IPC_CREAT)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Salut

    Si tu veux 3 sémaphores, inutile de passer par shmget(). Te suffit de les réserver via semget(key, 3, 0666 | IPC_CREAT)...
    J'ai besoin d'autres variables, pas que de sémaphores. Mais je note quand même ta réponse

    Apparemment le problème viendrait du fait que la mémoire partagée est déjà créée et que j'essaie de créer un segment plus grand. C'est assez contraignant puisque je dois nettoyer à chaque modification du code. Pourtant j'exécute cette ligne à chaque fin de programme (chez le processus père et chez les fils) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	shmdt(segment); // Détachement de la mémoire commune

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par KaNaRette Voir le message
    Apparemment le problème viendrait du fait que la mémoire partagée est déjà créée et que j'essaie de créer un segment plus grand. C'est assez contraignant puisque je dois nettoyer à chaque modification du code.
    Ou alors tu calcules dès le départ l'espace dont tu auras besoin pour tout ton programme...

    Citation Envoyé par KaNaRette Voir le message
    Pourtant j'exécute cette ligne à chaque fin de programme (chez le processus père et chez les fils) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	shmdt(segment); // Détachement de la mémoire commune
    shmdt() ne fait que détacher la mémoire du processus mais elle existe toujours dans l'ordinateur (normal puisque l'idée est que d'autres processus puissent aller récupérer les infos).
    Si tu veux nettoyer ta zone mémoire, il te faut alors appeler
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    shmctl(key, IPC_RMID)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Si tu veux nettoyer ta zone mémoire, il te faut alors appeler
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    shmctl(key, IPC_RMID)
    Merci, ça semble répondre parfaitement à mon problème.

    Merci à tous pour votre aide

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

Discussions similaires

  1. Communication entre deux processus pere-fils bloquante
    Par joffrey575 dans le forum Unix
    Réponses: 0
    Dernier message: 13/04/2015, 20h39
  2. Mémoire partagée entre deux processus
    Par Sutat dans le forum ALM
    Réponses: 8
    Dernier message: 04/02/2012, 13h35
  3. Communication par pipe entre deux processus
    Par mohamedz dans le forum POSIX
    Réponses: 9
    Dernier message: 02/03/2010, 17h50
  4. Partager un bloc mémoire entre deux processus ?
    Par bvsud dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 20/02/2010, 01h20
  5. Réponses: 4
    Dernier message: 21/08/2009, 10h48

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