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 :

Accès écriture/lecture mémoire partagée


Sujet :

Linux

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 67
    Points : 42
    Points
    42
    Par défaut Accès écriture/lecture mémoire partagée
    Bonjour, j'aimerais savoir comment utilisé les appels systèmes read/write dans le cas de communication interprocessus avec des segments de mémoire partagée. J'ai déjà chercher sur le net, mais les rares exemples que j'ai trouvé étaient un peu trop complexe pour mon niveau .

    Merci.

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    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 720
    Points : 31 043
    Points
    31 043
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ggwtf Voir le message
    Bonjour, j'aimerais savoir comment utilisé les appels systèmes read/write dans le cas de communication interprocessus avec des segments de mémoire partagée. J'ai déjà chercher sur le net, mais les rares exemples que j'ai trouvé étaient un peu trop complexe pour mon niveau .

    Merci.
    La mémoire partagée (shm) est une zone mémoire. C'est à dire un simple tableau d'octets.
    Tu écris dans ce tableau de la même façon que tu écris dans tes variables => elem[x]=valeur_a_stocker ou bien en utilisant des fonctions prévues à cet effet => memcpy() et tu récupères la valeur stockée de la même façon. La seule différence avec la mémoire de base de ton code c'est qu'il te faut d'abord attacher ta zone shm (stockée par le système) à un pointeur déclaré dans ton source pour pouvoir ensuite y accéder.



    Ci-joint un petit code simple pour écrire dans de la shm
    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
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    // BUT : Stocker des chaines de caractères dans une mémoire partagée          
    //
    // PRINCIPE : Le premier argument est la clef de la zone (hexadécimal)        
    //            Les autres arguments sont les chaines à y stocker               
    //                                                                            
    // USAGE : prog clef [chaine1 ...]                                            
    //	- Pas d'option                                                            
    //                                                                            
     
    #include <sys/types.h>						// Types prédéfinis "c"           
    #include <sys/mode.h>						// Modes et droits fichiers       
    #include <sys/ipc.h>						// Internal Process Comm.         
    #include <sys/shm.h>						// Mémoire partagée I.P.C.        
    #include <stdio.h>							// I/O fichiers classiques        
    #include <errno.h>							// Erreurs système                
     
    extern const char* const sys_errlist[];		// Liste messages erreurs         
     
    // Fonction principale 
    main(
    	int argc, 								// Nbre arguments                 
    	char *argv[])							// Ptr arguments                  
    {
    	// Déclaration des variables 
    	int shm_id;								// Identifiant de la zone         
    	int i;									// Indice de boucle               
    	char *shm_zone;							// Zone attachee                  
    	char *pt_zone;							// Ptr zone                       
    	key_t shm_key;							// Clef de la zone                
     
    	// Vérification au moins deux arguments 
    	if (argc <= 1)
    	{
    		fprintf(stderr, "Usage: %s clef [chaine1 ...]\n", argv[0]);
    		exit(errno);
    	}
     
    	// Conversion argument 1 (hexa) en nombre 
    	shm_key=strtoul(argv[1], NULL, 16);
     
    	// Creation/Ouverture de la zone 
    	if ((shm_id=shmget(shm_key, 0x10000, IPC_CREAT|0666)) == (-1))
    	{
    		fprintf(stderr, "ligne %u - shmget(0x%08x) - %s\n", __LINE__, shm_key, sys_errlist[errno]);
    		exit(errno);
    	}
    	printf("Zone mémoire 0x%x ouverte - valeur %d\n", shm_key, shm_id);
     
    	// Attachement de la zone 
    	shm_zone=shmat(shm_id, NULL, 0);
    	if (shm_zone == (-1))
    	{
    		fprintf(stderr, "ligne %u - shmat(%d) - %s\n", __LINE__, shm_id, sys_errlist[errno]);
    		exit(errno);
    	}
    	printf("Zone mémoire %d attachee a l'adresse 0x%x\n", shm_id, shm_zone);
     
    	// Copie de chaque argument (avec le NULL) dans la zone attachee 
    	pt_zone=shm_zone;
    	for (i=2; i < argc; i++)
    	{
    		// Copie de chaque caractere de l'argument (avec le NULL) 
    		memcpy(argv[i], pt_zone, strlen(argv[i]) + 1);
    		printf("\tchaine '%s'... memorisee en adresse 0x%08x\n", argv[i], ((unsigned short)pt_zone));
     
    		// Décalage du pointeur de zone 
    		pt_zone=pt_zone + strlen(argv[i]) + 1;
    	}
     
    	// Detachement de la zone 
    	if (shmdt(shm_zone) == (-1))
    	{
    		fprintf(stderr, "ligne %u - shmdt(%d) - %s\n", __LINE__, shm_zone, sys_errlist[errno]);
    		exit(errno);
    	}
    	printf("Zone mémoire %d détachée de l'adresse 0x%x\n", shm_id, shm_zone);
    }
    ... et un autre pour lire
    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
    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
    // BUT : Afficher le contenu d'une zone de mémoire partagée                   
    //                                                                            
    //                                                                            
    // PRINCIPE : Le premier argument est la clef de la zone (hexadécimal)        
    //            Si argument pas clef valide, il devient identifiant (décimal)   
    //            Le second est le format d'affichage (c, d, u, x)                
    //            Le troisieme est le nombre de caractères à afficher             
    //            Le programme affiche la zone caractère par caractère            
    //                                                                            
    // USAGE : prog clef/id [c/d/u/x] [nb]                                        
    //	- Pas d'option                                                            
    //                                                                            
     
    #include <sys/types.h>						// Types prédéfinis "c"           
    #include <sys/mode.h>						// Modes et droits fichiers       
    #include <sys/ipc.h>						// Internal Process Comm.         
    #include <sys/shm.h>						// Mémoire partagée I.P.C.        
    #include <stdio.h>							// I/O fichiers classiques        
    #include <errno.h>							// Erreurs système                
     
    extern const char* const sys_errlist[];		// Liste messages erreurs         
     
    #define SZ_DEFAUT				(100)		// Taille à afficher par défaut   
    #define FORMAT_DEFAUT			('c')		// Format d'affichage par défaut  
     
    // Fonction principale 
    main(
    	int argc, 								// Nbre arguments                 
    	char *argv[])							// Ptr arguments                  
    {
    	// Déclaration des variables 
    	char format; 							// Format d'affichage             
    	int shm_id;								// Identifiant de la zone         
    	int i;									// Indice de boucle               
    	int nb_affich;							// Nbre car. à afficher           
    	char *shm_zone;							// Zone attachée                  
    	char *pt_zone;							// Ptr zone                       
    	key_t shm_key;							// Clef de la zone                
     
    	// Vérification au moins un argument 
    	if (argc <= 1)
    	{
    		fprintf(stderr, "Usage: %s clef/id [c/d/u/x] [size]\n", argv[0]);
    		exit(errno);
    	}
     
    	// Conversion argument 1 (hexa) en nombre 
    	shm_key=strtoul(argv[1], NULL, 16);
     
    	// Récupération format demandé (si existant) 
    	format=(argc > 2) ?argv[2][0] :FORMAT_DEFAUT; 
     
    	// Récupération taille à afficher (si existant) 
    	nb_affich=(argc > 3) ?atoi(argv[3]) :SZ_DEFAUT;
     
    	// Ouverture de la zone si clef valide 
    	if ((shm_id=shmget(shm_key, 0, IPC_ALLOC)) == (-1))
    	{
    		fprintf(stderr, "ligne %u - shmget(0x%08x) - %s\n", __LINE__, shm_key, sys_errlist[errno]);
    		shm_id=strtoul(argv[1], NULL, 10);
    		printf("Clef 0x%08x invalide => Utilisation identifiant %d\n", shm_key, shm_id);
    	}
    	printf("Zone mémoire 0x%x ouverte - valeur %d\n", shm_key, shm_id);
     
    	// Attachement de la zone 
    	shm_zone=shmat(shm_id, NULL, SHM_RDONLY);
    	if (shm_zone == (-1))
    	{
    		fprintf(stderr, "ligne %u - shmat(%d) - %s\n", __LINE__, shm_id, sys_errlist[errno]);
    		exit(errno);
    	}
    	printf("Zone mémoire %d attachée à l'adresse 0x%x\n", shm_id, shm_zone);
     
    	// Affichage de chaque caractère de la zone attachée 
    	for (i=0, pt_zone=shm_zone; i < nb_affich; i++, pt_zone++)
    	{
    		switch (format)
    		{
    			case 'c': // Format caractère 
    				if (isprint(*pt_zone) || *pt_zone == '\n')
    					printf("%c", *pt_zone);
    				break;
    			case 'd': // Format décimal signé 
    				printf("%d ", *pt_zone);
    				break;
    			case 'u': // Format décimal non signé 
    				printf("%u ", *pt_zone);
    				break;
    			case 'x': // Format hexadécimal 
    				printf("0x%02x ", *pt_zone);
    				break;
    		}
    	}
    	fputs("\n\n", stdout);
     
    	// Détachement de la zone 
    	if (shmdt(shm_zone) == (-1))
    	{
    		fprintf(stderr, "ligne %u - shmdt(%d) - %s\n", __LINE__, shm_zone, sys_errlist[errno]);
    		exit(errno);
    	}
    	printf("Zone mémoire %d détachée de l'adresse 0x%x\n", shm_id, shm_zone);
    }

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 67
    Points : 42
    Points
    42
    Par défaut
    Merci pour ton exemple.
    Mais y a t-il moyen d'utiliser les A.S. read et write pour lire/écrire dans la shm? si oui, de quel manière?

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    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 720
    Points : 31 043
    Points
    31 043
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ggwtf Voir le message
    Merci pour ton exemple.
    Mais y a t-il moyen d'utiliser les A.S. read et write pour lire/écrire dans la shm? si oui, de quel manière?
    Ben non !!!
    Les fonctions read() et write() sont faites pour lire et écrire dans des périphériques, pas dans la mémoire !!!!!
    C'est comme si tu demandais "puis-je utiliser write() pour mettre 5 dans ma variable int i". Ca n'a pas de sens...

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 67
    Points : 42
    Points
    42
    Par défaut
    Donc ce cours (pp 32-33) ne serait pas juste alors?

  6. #6
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Si, le cours est juste, mais il utilise les IPC POSIX (shm_open pour la mémoire partagée) alors que Sve@r parle des IPC System V (shmget/shmat), qui sont quand même plus répandues.

    Donc avec shm_open on récupère effectivement un file descriptor, et la zone de mémoire partagée est accédée comme un fichier. Avec shmget/shmat, on récupère un pointeur vers une zone en mémoire sur laquelle la mémoire partagée est mappée.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 67
    Points : 42
    Points
    42
    Par défaut
    Citation Envoyé par matafan Voir le message
    Si, le cours est juste, mais il utilise les IPC POSIX (shm_open pour la mémoire partagée) alors que Sve@r parle des IPC System V (shmget/shmat), qui sont quand même plus répandues.

    Donc avec shm_open on récupère effectivement un file descriptor, et la zone de mémoire partagée est accédée comme un fichier. Avec shmget/shmat, on récupère un pointeur vers une zone en mémoire sur laquelle la mémoire partagée est mappée.
    Merci pour cet éclaircissement

Discussions similaires

  1. Réponses: 3
    Dernier message: 24/01/2011, 18h02
  2. droits d'accès en lecture écriture (débutant!)
    Par hucliez dans le forum Apache
    Réponses: 1
    Dernier message: 12/12/2008, 23h33
  3. Accès à la mémoire partagée
    Par thierryG dans le forum Windows
    Réponses: 3
    Dernier message: 26/10/2007, 14h20
  4. Réponses: 4
    Dernier message: 15/07/2007, 00h07
  5. Réponses: 7
    Dernier message: 27/06/2005, 11h33

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