Таким образом, следующий код должен выполнять следующее:
- Основной процесс создает N_READ число дочерних процессов и затем бесконечно печатает некоторые строки.
- Дочерние такжепечатать несколько строк бесконечно.
- Когда основной процесс получает сигнал 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);
}
}