Gaëtan
Gaëtan

Reputation: 29

Issue with shared memory in C

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

Answers (1)

John Bollinger
John Bollinger

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:

  1. 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.

  2. 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

Related Questions