Passer une structure dans une shared memory POSIX

Passer une structure dans une shared memory POSIX - C - Programmation

Marsh Posté le 13-04-2005 à 16:17:10    

Salut,
j'ai un souci pour passer une structure dans une shared memory. Un ps client envoye une structure via un pipe nomme au code ci-dessous et lui-meme dois l'envoyer dans une memoire partagee qui est lue par 3eme ps de supervision, et la cc me met une erreur de casting. J'ai essaye en envoyant un char a la place de la structure et la pas de probleme.
Une idée?
 
 
 
 
int  ret_val ;
struct transport                          
 {                                    
 int actuel ;                          
 int dest ;                            
 int NB_pass;                          
 };    
 
/*___________________________________DECLARATIONS POUR MEMOIRE PARTAGEE GLOBLALE_____*/
int shm_etage1;
//int shm_etage2;
caddr_t   shm_ptr1;
//caddr_t   shm_ptr2;
 
main (int argc, char *argv[])
{
 printf("\n\t\tPROGRAMME PRINCIPAL" );
 int lire;
 char lettre = 'A';
 int i;
 
 struct transport trajet;
 int t=1;
 trajet.actuel=0;
 trajet.dest=0;
 trajet.NB_pass=0;
 lire = open("tube", O_RDONLY);
 shm_etage1 = shm_open ( "/tmp/etage1", (O_CREAT | O_RDWR), 0 );
 //shm_etage2 = shm_open ( "/tmp/etage2", (O_CREAT | O_RDWR), 0 );
 ret_val = fchmod ( shm_etage1 , (mode_t) S_IRWXG | S_IRWXU | S_IRWXO );
 //ret_val = fchmod ( shm_etage2 , (mode_t) S_IRWXG | S_IRWXU | S_IRWXO );  
 ret_val = ftruncate (shm_etage1, 3);
 //ret_val = ftruncate (shm_etage2, 3);  
 shm_ptr1 = mmap ((caddr_t) 0, sizeof(struct transport), PROT_WRITE|PROT_READ, MAP_SHARED, shm_etage1, 0 );
 //shm_ptr2 = mmap ((caddr_t) 0, sizeof(struct transport), PROT_WRITE|PROT_READ, MAP_SHARED, shm_etage2, 0 );      
 while(trajet.NB_pass != -1)
 {
 read(lire,(char*) &trajet,sizeof(struct transport));
 printf("\nTrajet %d : %d passagers vont de l'etage %d a l'etage %d", t++, trajet.NB_pass, trajet.actuel, trajet.dest);
 *shm_ptr1= trajet;
 }
 //close("tube" );
 printf("\nFIN PROGRAMME" );
 
ret_val = munmap ( shm_ptr1 , sizeof(struct transport) );
//ret_val = munmap ( shm_ptr2 , sizeof(struct transport) );  
ret_val = close ( shm_etage1 );
//ret_val = close ( shm_etage2 );
ret_val = shm_unlink ( "/tmp/etage1" );
//ret_val = shm_unlink ( "/tmp/etage2" );
}
 
 
merci!

Reply

Marsh Posté le 13-04-2005 à 16:17:10   

Reply

Marsh Posté le 13-04-2005 à 16:28:34    

Ah  oui j'oubliais l'erreur de compilation concerne la ligne
 
*shm_ptr1=trajet;
 
merci

Reply

Marsh Posté le 13-04-2005 à 17:34:01    

Une structure ca se copie avec "memcpy", pas "=" ...

Reply

Marsh Posté le 13-04-2005 à 17:36:51    

vais essayer, tu as le prototype?
 
et puis la fonction vide aussi la memoire ou ne fait que copier ce qu'il y a dedans?

Reply

Marsh Posté le 13-04-2005 à 17:38:19    

matafan a écrit :

Une structure ca se copie avec "memcpy", pas "=" ...


Les deux, mon général...
 
structure != tableau...
 
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 13-04-2005 à 17:39:25    

cobbleguard a écrit :

et puis la fonction vide aussi la memoire ou ne fait que copier ce qu'il y a dedans?


"vider la mémoire", ça n'a aucun sens.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 13-04-2005 à 17:45:41    

j'ai modifie la ligne
*shm_ptr1= trajet;  
par  
 struct transport shm_ptr1=  trajet;
et ca passe a la compilation mais dans mon ps3 j'ai toujours l'erreur pour la recuperer et donc je ne c pas si ca marche
 
 
/*___________________________________DECLARATIONS POUR MEMOIRE PARTAGEE GLOBLALE_____*/
int shm_etage1;
int shm_etage2;
caddr_t   shm_ptr1;
 
 
main (int argc, char *argv[])
{
  struct transport trajet;
  shm_etage1 = shm_open ( "/tmp/etage1", ( O_RDWR), 0 );  
  shm_ptr1 = mmap ((caddr_t) 0, 3, PROT_READ, MAP_SHARED, shm_etage1, 0 );
  sleep(2);
    trajet =   *shm_ptr1;
    printf("actuel %d, dest %d, nbpass %d", trajet.actuel, trajet.dest, trajet.NB_pass);
    //printf("\n en memoire : %c", d);
    ret_val = munmap ( shm_ptr1 , 3 );
    ret_val = close ( shm_etage1 );
 
}
 
erreur a la ligne
    trajet =   *shm_ptr1;

Reply

Marsh Posté le 13-04-2005 à 18:43:14    

ton utilisattion de mmap est mauvaise. Lis le man. Conforme toi au prototype.
 
sinon tu ne peux pas dereferencé un pointer void.


Message édité par Taz le 13-04-2005 à 18:59:31
Reply

Marsh Posté le 13-04-2005 à 20:12:03    

Emmanuel Delahaye a écrit :

Les deux, mon général...
 
structure != tableau...


 
:heink:

Reply

Marsh Posté le 13-04-2005 à 22:22:57    

J'ai remodifie le le code du PS3 en commancant par caster shm_ptr1, ca passe la compil mais plante a l'execution segmentation fault (core dumped)
 
main (int argc, char *argv[])
{
 
struct transport* transp_shm_ptr1 = (struct transport*) shm_ptr1;
 
 
  struct transport trajet;
  shm_etage1 = shm_open ( "/tmp/etage1", ( O_RDWR), 0 );  
  shm_ptr1 = mmap ((caddr_t) 0, 3, PROT_READ, MAP_SHARED, shm_etage1, 0 );
  sleep(2);
  trajet = *transp_shm_ptr1;
    //trajet =   *shm_ptr1;
    printf("actuel %d, dest %d, nbpass %d", trajet.actuel, trajet.dest, trajet.NB_pass);
    //printf("\n en memoire : %c", d);
    ret_val = munmap ( shm_ptr1 , 3 );
    ret_val = close ( shm_etage1 );
 
}

Reply

Marsh Posté le 13-04-2005 à 22:22:57   

Reply

Marsh Posté le 13-04-2005 à 22:41:29    

struct transport* transp_shm_ptr1 = (struct transport*) shm_ptr1;  
 
 
... ou est déclaré shm_ptr1 ? ou est-il initialisé ?
 
soit un peu sérieux.

Reply

Marsh Posté le 13-04-2005 à 23:18:25    

struct transport* transp_shm_ptr1 = (struct transport*) shm_ptr1;  
 
 
... ou est déclaré shm_ptr1 ? ou est-il initialisé ?  
 
soit un peu sérieux.
 
 
il est declare en global juste apres les includes, pensais pas devoir afficher tout...
 
 
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <semaphore.h>
#include <sys/mode.h>
 
struct ascenceur
 {
 int id;
 int charge;
 int portes;
 int NB_in;
 int NB_max;
 int dest;
 };
 
struct etage
 {
 int id;
 int occupation;
 int asc_stop;
 };  
 
struct transport                          
 {                                    
 int actuel ;                          
 int dest ;                            
 int NB_pass;                          
 };    
 
/*____________________________________DECLARATIONS POUR SEMAPHORES NOMMES_____________*/
sem_t *ptr_sema=NULL ;
sem_t *ptr_sema2=NULL;
int oflags = O_CREAT ;
mode_t mode = 0644 ;
const char semname1 [] = "/tmp/semap1" ;
const char  semname2 [] = "/tmp/semap2" ;
unsigned int value = 1 ;
int  ret_val ;
 
 
/*___________________________________DECLARATIONS POUR MEMOIRE PARTAGEE GLOBLALE_____*/
int shm_etage1;
int shm_etage2;
caddr_t   shm_ptr1;
 
 
main (int argc, char *argv[])
{
 
struct transport* transp_shm_ptr1 = (struct transport*) shm_ptr1;
 
 
  struct transport trajet;
  shm_etage1 = shm_open ( "/tmp/etage1", ( O_RDWR), 0 );  
  shm_ptr1 = mmap ((caddr_t) 0, 3, PROT_READ, MAP_SHARED, shm_etage1, 0 );
  sleep(2);
  trajet = *transp_shm_ptr1;
    //trajet =   *shm_ptr1;
    printf("actuel %d, dest %d, nbpass %d", trajet.actuel, trajet.dest, trajet.NB_pass);
    //printf("\n en memoire : %c", d);
    ret_val = munmap ( shm_ptr1 , 3 );
    ret_val = close ( shm_etage1 );
 
}
 
pour l'initialisation, c'est la valeur de retour de la fonction mmap
 

Reply

Marsh Posté le 13-04-2005 à 23:27:51    

je crois que t'as raté le 'soit un peu sérieux'
 
prends tes yeux, et regarde la valeur de transp_shm_ptr1

Reply

Marsh Posté le 14-04-2005 à 00:42:50    

Citation :

ce truc me prend la tete, je me doute bien que tu as une idee vu ce que te me marques, si tu m'en faisait part au lieu de balancer des vannes ca serait sympa non?


tu ferais mieux de faire des
 
printf("%p\n", transp_shm_ptr1);
 
plutôt que de m'envoyer des MP

Reply

Marsh Posté le 14-04-2005 à 11:12:27    

http://linuxfr.org/forums/19/8079.html
 
en plus on te dit partout la même chose ...

Reply

Marsh Posté le 14-04-2005 à 11:39:54    

Taz a écrit :

http://linuxfr.org/forums/19/8079.html
 
en plus on te dit partout la même chose ...


 
Ouh comme ça casse... :lol:

Reply

Marsh Posté le 15-04-2005 à 19:02:55    

voila g corrige et ca marche.....
 
code PS2:
 
 
 
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <semaphore.h>
#include <sys/mode.h>
 
struct ascenceur
 {
 int id;
 int charge;
 int portes;
 int NB_in;
 int NB_max;
 int dest;
 };
 
struct etage
 {
 int id;
 int occupation;
 int asc_stop;
 };  
 
 
 
/*____________________________________DECLARATIONS POUR SEMAPHORES NOMMES_____________*/
sem_t *ptr_sema=NULL ;
sem_t *ptr_sema2=NULL;
int oflags = O_CREAT ;
mode_t mode = 0644 ;
const char semname1 [] = "/tmp/semapn" ;
const char  semname2 [] = "/tmp/semapm" ;
unsigned int value = 1 ;
 
 
 
 
int  ret_val ;
 struct transport                          
  {                                    
  int actuel ;                          
  int dest ;                            
  int NB_pass;                          
  }trajet, trajet2;    
 
/*___________________________________DECLARATIONS POUR MEMOIRE PARTAGEE GLOBLALE_____*/
int shm_etage1;
int shm_etage2;
caddr_t   shm_ptr1;
 
 
main (int argc, char *argv[])
{
 printf("\n\t\tPROGRAMME PRINCIPAL" );
 int lire;
 struct transport trajet;
 int t=1;
 trajet.actuel=3;
 trajet.dest=4;
 trajet.NB_pass=5;
 
 
 /*ouverture du tube*/
 lire = open("tube", O_RDONLY);
 /*creation memoire partagee*/
 shm_etage1 = shm_open ( "/tmp/etage1", (O_CREAT | O_RDWR), 0 );
 if(shm_etage1 == -1)
 perror("\nopen shm_etage1 failled:" );
 /*modification des droits d'acces*/
 ret_val = fchmod ( shm_etage1 , (mode_t) S_IRWXG | S_IRWXU | S_IRWXO );
 if(ret_val == -1)
 perror("\nfchmod etage 1 failled:" );  
 /*creation d'un semaphore nomme*/                                    
 ptr_sema = sem_open ( semname1, oflags, mode, value );        
 if ( ptr_sema == (void *) -1 )                                                
 { perror ( "\n\rMAIN : sem_open failed->sem1 !!!" ); exit( 1 ); }                        
                                                                   
                                                                               
 /*creation d'un semaphore nomme*/                                    
                                                                                     
 ptr_sema2 = sem_open ( semname2, oflags, mode, value );      
 if ( ptr_sema == (void *) -1 )                                                
 { perror ( "\n\rMAIN : sem_open failed ->sem2!!!" ); exit( 1 ); }                      
 printf("\n*****OK  2 SEMAPHORES CREES*****\n" );                      
 
 
 /*positionnement de la taille de la memoire partagee*/
 ret_val = ftruncate (shm_etage1, sizeof(struct transport));
 if(ret_val == -1)
 perror("\nftruncate etage 1 failled:" );
 /*mapping de la zone*/
 shm_ptr1 =  mmap ( 0, sizeof(struct transport), PROT_WRITE|PROT_READ, MAP_SHARED, shm_etage1, 0 );
 if(ret_val == -1)
 perror("\nmmap etage 1 failled:" );
 /*casting du pointeur d'adresse*/
 struct transport* transp_shm_ptr1 = (struct transport*) shm_ptr1;      
 
 while(trajet.NB_pass != -1)
 {
  /*lecture du tube*/
  read(lire,(char*) &trajet,sizeof(struct transport));
  printf("\nTrajet %d : %d passagers vont de l'etage %d a l'etage %d", t++, trajet.NB_pass, trajet.actuel, trajet.dest);
/*BLOQUAGE ACCES MEMOIRE -->EVITER VIOLATION DE PARTAGE */                                          
  ret_val = sem_wait ( ptr_sema ) ;                
  if ( ret_val == -1 )                              
  { perror ( "\n\rMAIN : sem_wait failed !!!" );  }
 
  /*ecrire en memoire*/
  *transp_shm_ptr1 =  trajet;
 
/*DEBLOQUAGE ACCES MEMOIRE*/                              
  ret_val = sem_post ( ptr_sema ) ;                
  if ( ret_val == -1 )                              
  { perror ( "\n\rMAIN : sem_post failed !!!" );  }
/*VALIDATION POUR SYNCHRO PROCESSUS*/                    
  ret_val = sem_post ( ptr_sema2) ;                
  if ( ret_val == -1 )                              
  { perror ( "\n\rMAIN : sem_post failed !!!" );  }
 
 
 
 
 //sleep(4);
 
 
}
 
/*FERMETURE SEMAPHORE*/                                                    
 ret_val = sem_close (ptr_sema);                          
 if (ret_val == -1)                                                        
 { perror ("\n\rMAIN : sem_close failed !!!" );  }                          
 /*DESTRUCTION SEMAPHORE*/                                                
 ret_val = sem_unlink (semname1);                                          
 if (ret_val == -1)                                                        
 { perror ("\n\rMAIN : sem_unlink failed !!!" );  }                        
 printf("\n\r*****Fermeture et destruction de /tmp/semapm*****\n" );        
                                                                     
 ret_val = sem_close (ptr_sema2);                                  
 if (ret_val == -1)                                                        
 { perror ("\n\rMAIN : sem_close failed !!!" );  }                          
                                                                           
 ret_val = sem_unlink (semname2);                                          
 if (ret_val == -1)                                                        
 { perror ("\n\rMAIN : sem_unlink failed !!!" );  }                        
  printf("\n\r*****Fermeture et destruction de /tmp/semapn*****\n" );      
 
 
printf("\nFIN PROGRAMME" );
/*de-mapping de la memoire*/
ret_val = munmap ( shm_ptr1 , sizeof(struct transport) );
/*fermeture memoire partagee*/  
ret_val = close ( shm_etage1 );
/*destruction objet memoire*/
ret_val = shm_unlink ( "/tmp/etage1" );
}
 
 
code PS3
 
 
 
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <semaphore.h>
#include <sys/mode.h>
 
struct ascenceur
 {
 int id;
 int charge;
 int portes;
 int NB_in;
 int NB_max;
 int dest;
 };
 
struct etage
 {
 int id;
 int occupation;
 int asc_stop;
 };  
 
struct transport                          
 {                                    
 int actuel ;                          
 int dest ;                            
 int NB_pass;                          
 };    
 
/*____________________________________DECLARATIONS POUR SEMAPHORES NOMMES_____________*/
sem_t *ptr_sema=NULL ;
sem_t *ptr_sema2=NULL;
int oflags = O_CREAT ;
mode_t mode = 0644 ;
const char semname1 [] = "/tmp/semapn" ;
const char  semname2 [] = "/tmp/semapm" ;
unsigned int value = 0 ;
int  ret_val ;
 
 
/*___________________________________DECLARATIONS POUR MEMOIRE PARTAGEE GLOBLALE_____*/
int shm_etage1;
int shm_etage2;
caddr_t   shm_ptr1;
 
 
main (int argc, char *argv[])
{
 struct transport* transp_shm_ptr1;
 struct transport trajet;  
 trajet.actuel=0;
 trajet.dest=0;
 trajet.NB_pass=0;
 
 printf("\n\t\tSUPERVISION" );
 printf("\n\t\t***********" );
 
 // sleep(4);
 
  /*ouverture de la memoire partagee*/
  shm_etage1 = shm_open ( "/tmp/etage1", ( O_RDWR), 0 );
  if(shm_etage1 == -1)
  perror("\nopen etage 1 failled:" );    
printf("\nmem ouverte" );
  sleep(2);
  /*mapping de la memoire*/
  shm_ptr1=mmap(0,sizeof(struct transport),PROT_READ,MAP_SHARED,shm_etage1,0);
  if(ret_val == -1)
  perror("\nmmap etage 1 failled:" );
printf("\nmem mappee" );  
  /*casting du pointeur d'adresse*/
  transp_shm_ptr1=(struct transport*) shm_ptr1;
/*OUVERTURE SEMAPHORE NOMME*/
            ptr_sema = sem_open ( semname1, oflags, mode, value );
  if ( ptr_sema == (void *) -1 )
  {perror ( "\n\rMAIN : sem_open failed !!!" );
   exit(1);}
printf("\nsem1 ouvert" );    
/*OUVERTURE DU SEMAPHORE NOMME DE SYNCHRONISATION*/
         ptr_sema2 = sem_open ( semname2, oflags, mode, value );
  if ( ptr_sema == (void *) -1 )
  {perror ( "\n\rMAIN : sem_open failed !!!" );
  exit(1);}  
printf("\nsem2 ouvert" );  
  while(transp_shm_ptr1->NB_pass != -1)              
   {      
printf("\nDans boucle" );
/*ESSAIS DE LECTURE SANS BLOQUAGE*/
   ret_val = sem_trywait ( ptr_sema2 ) ;
printf("\nsem try wait" );
/*BLOQUAGE ACCES MEMOIRE-->POUR EVITER VIOLATION DE PARTAGE*/
   ret_val = sem_wait ( ptr_sema ) ;
   if ( ret_val == -1 )
    { perror ( "\n\rMAIN : sem_wait failed sem_mem (PTR_SEMA)!!!" );  }
printf("\nsem wait" );    
   /*lecture de la memoire champ a champ*/
   trajet.actuel=transp_shm_ptr1->actuel;
   trajet.dest = transp_shm_ptr1->dest;
   trajet.NB_pass = transp_shm_ptr1->NB_pass;
 
 
     printf("\nactuel %d, dest %d, nbpass %d", trajet.actuel, trajet.dest, trajet.NB_pass);
/*DEBLOQUAGE ACCES MEMOIRE*/
   ret_val = sem_post ( ptr_sema ) ;
   if ( ret_val == -1 )
   { perror ( "\n\rMAIN: sem_post failed sem_mem  for PTR_SEMA!!!" );  }
   
   }/*fin while*/
   
     
  //sleep(4);
 
/*FERMETURE SEMAPHORE*/
ret_val = sem_close (ptr_sema);
if (ret_val == -1)
{ perror ("\n\rMAIN : sem_close failed !!!" );  }
 
 
ret_val = sem_close (ptr_sema2);
if (ret_val == -1)
{ perror ("\n\rMAIN : sem_close failed !!!" );  }  
 
                                                                                                                                                                                                                                   
 
/*de mapping de la memoire partagee*/                                                                      
ret_val = munmap ( shm_ptr1 , sizeof(struct transport) );
if (ret_val == -1)                              
{ perror ("\n\rMAIN : munmap failed !!!" );  }
/*fermeture de la memoire*/
ret_val = close ( shm_etage1 );
if (ret_val == -1)
{ perror ("\n\rMAIN : close failed !!!" );  }                                
 
}
 

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed