Reputation: 63
So the following code is supposed to do the following:
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
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