Reputation: 29
I have an issue with a shared memrory in C.
I think I allocate this shared memory variable but i can not delete it and so i can't launch my programm without restarting my computer because i got the issue : this shared memory already exists.
Moreover, i am not sure about my semaphore using.
I have to use a shared variable an 2 processus should increment it.
void prendre(int semid, int no){
struct sembuf op[1];
int er;
op[0].sem_num=no;
op[0].sem_op=-1;
op[0].sem_flg=0;
er=semop(semid,op,1);
if(er==-1) { perror("erreur semop prendre \n"); exit(1);}
}
void rendre(int semid, int no){
struct sembuf op[1];
int er;
op[0].sem_num=no;
op[0].sem_op=1;
op[0].sem_flg=0;
er=semop(semid,op,1);
if(er==-1) { perror("erreur semop prendre \n"); exit(1);}
}
void init_semaphore(int semid){
int er;
union semun{
int val;
struct semid_ds *buf;
ushort *array;
}arg;
arg.val=1;
er = semctl(semid,0,SETVAL,arg);
if(er == -1) {perror("erreur semctl\n");exit(1);}
}
void *runDuprocessus(int *pid, int *mem){
int k=0;
for (k=0;k<1e6;k++){
*mem += 1;
}
printf("globale processus %d = %d\n",*pid, *mem);
exit(1);
}
int creationSegment(int size, char *name, int cle){
int shmid ; // l'identificateur de la memoire partagee
key_t clef ; // la clef associee au segment
clef = ftok(name,(key_t) cle) ;
shmid = shmget( clef, size, IPC_CREAT|IPC_EXCL|SHM_R|SHM_W ) ;
if ( shmid== -1 ) {
perror("Echec creation segment mémoire partagée!\n") ;
exit(1) ;
}
return shmid ;
}
int main(void){
int destru;
pid_t pid;
int semid=0;
int *mem;
int shmid; // identifiant du segment de la mémoire partagé
int flag = 0; // flag du segment
char *name = (char*) malloc(25*sizeof(char));
int size = sizeof(int);
key_t cle;
int tmp=0;
// Création du segment de mémoire partagé
name = "creationSegmentParatage.c";
shmid = creationSegment(size,name,2);
// Création du sémaphore
cle = ftok("proccessus.c",0);
if(cle==(key_t) -1) {perror("erreur ftok\n");exit(1);}
semid=semget(cle,1,IPC_CREAT|0666);
if(semid == -1) {perror("erreur semget\n");exit(1);}
init_semaphore(semid); //Initialisation du semaphore
// Création du fork
pid = fork();
if(pid < 0){
printf("Erreur fork creation !\n");
exit(0);
}else if(pid == 0){
//printf("Processus fils : \n");
mem =shmat(shmid,0,flag);//Attachement segment mémoire
if(mem == (int*)-1){
perror("Probleme attachement segment mémoire\n");
exit(1);
}
prendre(semid,0); //Prise semaphore
runDuprocessus(&pid,mem);
tmp = shmdt(mem);
if(tmp ==-1){ //Détachement du segment mémoire
perror("detachement impossible\n") ;
exit(1) ;
}
rendre(semid,0); //Libération semaphore
}
else {
//printf("Processus père : \n");
mem = shmat(shmid,0,flag); //Rattachement segment mémoire
if(mem == (int*)-1){
perror("Probleme attachement segment mémoire\n");
exit(1);
}
prendre(semid,0);
runDuprocessus(&pid,mem);
tmp = shmdt(mem);
if(tmp ==-1){ //Détachement du segment mémoire
perror("detachement impossible\n") ;
exit(1) ;
}
rendre(semid,0);
}
wait(NULL); //Attente du fils
//Destruction du segment mémoire
destru = shmctl(shmid,IPC_RMID,NULL);
if (destru == -1){
perror("Erreur lors de la destruction") ;
exit(1) ;
}
//Destruction du semaphore
//sem_destroy(semid);
return 0;
}
Thank you for your future help !
Upvotes: 2
Views: 437
Reputation: 180201
I think I allocate this shared memory variable but i can not delete it and so i can't launch my programm without restarting my computer because i got the issue : this shared memory already exists.
You obtain the shared-memory segment like so ...
shmid = shmget( clef, size, IPC_CREAT|IPC_EXCL|SHM_R|SHM_W ) ;
The flag combination IPC_CREAT|IPC_EXCL
insists that the shared-memory segment be freshly created. If a segment already exists for the specified key, then the call will fail with an error, which is what you seem to be observing. Shared memory segments persist until they are explicitly removed, and there are many ways that your program can exit without removing the segment.
There are two main options:
If it's acceptable for the program to use a shared-memory segment created during a previous run -- or another contemporaneous one -- then you can remove the IPC_EXCL
flag from the shmget()
call.
If you really do need to ensure that you create a new, fresh segment for each run, then you must ensure that the segment is removed when no longer needed. In particular, if the need for the segment ends when the program exits then you should ensure that once the segment is created, the program does not exit -- at least not normally -- without removing the segment again.
Note, too, that if each run of the program requires its own shared-memory segment then you must either use distinct keys for distinct runs, or accept that only one instance of the program can run at a time, and that if it exits abnormally then you may need to manually clean up -- with ipcrm
, for example.
If you have specific questions about the semaphore usage, then those would be better posed as a separate question.
Upvotes: 3