Veraeldr Atmyrkr
Veraeldr Atmyrkr

Reputation: 63

Named semaphores in C are not deleted after a signal handler call

So the following code is supposed to do the following:

  1. The main process creates N_READ number of children processes and then proceeds to print some lines endlessly.
  2. The children also print some lines endlessly.
  3. When the main process receives a SIGINT signal (CTRL^C from the terminal in this case) he must send a SIGTERM to all his children, wait for them to finish and then delete all the semaphores used.

The use of named semaphores is justified by the fact that this is simulation of the readers-writers problem giving priority to the readers.

However when I end the program and start it again the semaphores have not been deleted, as I get an "semaphore already exists" error and they are in fact in /dev/shm.

P.D. This is college homework and they say global variables are not permitted.

Thank you in advance and here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>

#define SEM1 "/example_sem1"
#define SEM2 "/example_sem2"
#define SEM3 "/example_sem3"

#define N_READ 1
#define SECS 0

int  valor_semaforo(sem_t *sem) {
    int sval;

    if (sem_getvalue(sem, &sval) == -1) {
        perror("sem_getvalue");
        sem_unlink(SEM1);
        sem_unlink(SEM2);
        sem_unlink(SEM3);
        exit(EXIT_FAILURE);
    }

   return sval;
}

void manejador_SIGINT(int sig) {

    kill(0,SIGTERM);
    while(wait(NULL)>0);
/*xq no llega xq*/
    sem_unlink(SEM1);
    sem_unlink(SEM2);
    sem_unlink(SEM3);

    exit(EXIT_SUCCESS);
}

int main(void) {
    sem_t *sem_write = NULL,*sem_read = NULL,*sem_count = NULL;
    pid_t pid[N_READ];
    int i;
    struct sigaction act;

    sigemptyset(&(act.sa_mask));
    act.sa_flags = 0;

    act.sa_handler = manejador_SIGINT;
    if (sigaction(SIGINT, &act, NULL) < 0) {
        perror("sigaction");
        exit(EXIT_FAILURE);
    }

    if ((sem_write = sem_open(SEM1, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 1)) == SEM_FAILED) {
        perror("sem_open");
        exit(EXIT_FAILURE);
    }
    if ((sem_read = sem_open(SEM2, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 1)) == SEM_FAILED) {
        perror("sem_open");
        exit(EXIT_FAILURE);
    }
    if ((sem_count = sem_open(SEM3, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0)) == SEM_FAILED) {
        perror("sem_open");
        exit(EXIT_FAILURE);
    }



    for(i=0;i<N_READ;i++){
        pid[i] = fork();
        if (pid[i] < 0) {
            perror("fork");
            exit(EXIT_FAILURE);
        }
        if (pid[i] == 0) {

            sigemptyset(&(act.sa_mask));
            act.sa_flags = 0;

            act.sa_handler = SIG_IGN;
            if (sigaction(SIGINT, &act, NULL) < 0) {
                perror("sigaction");
                exit(EXIT_FAILURE);
            }
            while(1){

                sem_wait(sem_read);
                sem_post(sem_count);
                if(valor_semaforo(sem_count)==1)
                    sem_wait(sem_write);
                sem_post(sem_read);

                printf("R-INI %d\n",getpid());
                fflush(stdout);
                sleep(SECS);
                printf("R-FIN %d\n",getpid());
                fflush(stdout);


                sem_wait(sem_read);
                sem_wait(sem_count);
                if(valor_semaforo(sem_count)==0)
                    sem_post(sem_write);
                sem_post(sem_read);
            }

        }
    }
        while(1){
            sem_wait(sem_write);
            printf("W-INI %d\n",getpid());
            fflush(stdout);
            sleep(SECS);
            printf("W-FIN %d\n",getpid());
            fflush(stdout);
            sem_post(sem_write);
        }    
    }

Upvotes: 0

Views: 391

Answers (1)

Veraeldr Atmyrkr
Veraeldr Atmyrkr

Reputation: 63

As @Jonathan said, the SIGTERM signal I use does terminate the process that should clean up the semaphores. By ignoring the signal in the parent process, everything works well.

Upvotes: 1

Related Questions