Именованные семафоры в C не удаляются после вызова обработчика сигнала - PullRequest
0 голосов
/ 27 мая 2019

Таким образом, следующий код должен выполнять следующее:

  1. Основной процесс создает N_READ число дочерних процессов и затем бесконечно печатает некоторые строки.
  2. Дочерние такжепечатать несколько строк бесконечно.
  3. Когда основной процесс получает сигнал SIGINT (в данном случае CTRL ^ C от терминала), он должен отправить SIGTERM всем своим детям, дождаться их завершения и затем удалить всеИспользуемые семафоры.

Использование именованных семафоров оправдывается тем фактом, что это симуляция задачи читателей-писателей с приоритетом читателей.

Однако, когда я заканчиваю программуи запустите его снова, семафоры не были удалены, так как я получаю ошибку «семафор уже существует», и они фактически находятся в /dev/shm.

PD. Это домашняя работа колледжа, и они говорят, что глобальные переменные не являютсяразрешено.

Заранее спасибо и вот код:

#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);
        }    
    }

1 Ответ

0 голосов
/ 30 мая 2019

Как сказал @Jonathan, сигнал SIGTERM, который я использую, завершает процесс, который должен очистить семафоры.При игнорировании сигнала в родительском процессе все работает хорошо.

...