Я пытаюсь обрабатывать сигналы SIGTERM и SIGUSR1 между 4 процессами (3 детей + 1 отец), но я не знаю, почему signal()
не вызывает обработчик. Может кто-нибудь мне помочь?Почему сигнал системного вызова() не вызывает вызов обработчика?
Это выход, как я ожидал:
pid of father of all: 13192
The father 13192 is waiting to all children die to too
Child1: pid = 13196 - parent's pid: 13192
Child2: pid = 13197 - parent's pid: 13192
Child3: pid = 13198 - parent's pid: 13192
Sending user signal
user signal sent
Into the interrupt_handler
The child1 13196 is going to be killed immediately
The child2 13197 is going to be killed later
The child2 13197 is going to kill itself now
Child3: pid = 13198 - parent's pid: 13192
Sending user signal
user signal sent
Into the interrupt_handler
The child3 13198 is going to be killed immediately
Это выход я получаю:
pid of father of all: 13192
The father 13192 is waiting to all children die to too
Child1: pid = 13196 - parent's pid: 13192
Child2: pid = 13197 - parent's pid: 13192
Child3: pid = 13198 - parent's pid: 13192
Sending user signal
user signal sent
Child1: pid = 13196 - parent's pid: 13192
Child2: pid = 13197 - parent's pid: 13192
Child3: pid = 13198 - parent's pid: 13192
Sending user signal
user signal sent
Child1: pid = 13196 - parent's pid: 13192
...
Как вы можете видеть, INTERRUPT_HANDLER не была вызвана для обработки сигнала. Это проблема.
Вот весь мой код:
#include <errno.h> // errno and error codes
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // for fork()
#include <stddef.h>
#include <float.h>
#include <sys/types.h> // for wait()
#include <sys/stat.h>
#include <sys/ipc.h> // for all IPC function calls
#include <sys/shm.h> // for shmget(), shmat(), shmctl()
#include <sys/sem.h> // for semget(), semop(), semctl()
#include <sys/wait.h> // for wait()
#include <sys/unistd.h>
#include <signal.h> // for kill(), sigsuspend(), others
pid_t child1, child2, child3;
int count_tens=0;
void interrupt_handler(int signal){
printf("Into the interrupt_handler\n");
if (signal==SIGUSR1)
{
count_tens++;
if(count_tens==1)
{
printf("The child1 %d is going to be killed immediately\n",getpid());
if(!kill(child1,SIGKILL))
perror("Did not kill (1)");//kills child1
printf("The child2 %d is going to be killed later\n",getpid());
if(!kill(child2,SIGTERM))
perror("Did not kill (2)");//let the child2 goes through interrupt_handler
} else if(count_tens==2)
{
printf("The child3 %d is going to be killed immediately\n",getpid());
//main(); //restart application
raise(SIGKILL); //child3 dies. At this point all children have died.
}
}
if (signal==SIGTERM){
printf("The child2 %d is going to kill itself now\n",getpid());
raise(SIGKILL);
}
}
int main(){
if ((signal(SIGTERM, interrupt_handler) == SIG_ERR) || (signal(SIGUSR1, interrupt_handler) == SIG_ERR)) {
printf("Error while setting a signal handler\n");
exit(EXIT_FAILURE);
}
child1=fork();
if (child1<0) { perror("fork"); exit(errno);}
if(child1==0){
while(1){
sleep(4);
printf("Child1: pid = %d - parent's pid: %d\n",getpid(),getppid());
}
}
child2=fork();
if(child2<0) { perror("fork"); exit(errno);}
if(child2==0){
while(1){
sleep(5);
printf("Child2: pid = %d - parent's pid: %d\n",getpid(),getppid());
}
}
child3=fork();
if(child3<0) { perror("fork"); exit(errno);}
if(child3==0){
while(1){
sleep(6);
printf("Child3: pid = %d - parent's pid: %d\n",getpid(),getppid());
printf("Testando: Child1 pid = %d, Child2 pid = %d, Child3 pid = %d\n",child1,child2,child3);
printf("Sending user signal\n");
kill(getppid(), SIGUSR1);
printf("user signal sent\n");
}
}
printf("pid of father of all: %d\n",getpid());
printf("The father %d is waiting to all children die to too\n",getpid());
waitpid(child3, NULL, 0); // PARENT blocks until 3th CHILD ends
return 0;
}
Когда 'ожидания()' прерывается сигналом, он возвращает '-1' с' errno' установлен в 'EINTR'. Таким образом, цикл while в конце будет завершен после первого сигнала. – Barmar
@Barmar, спасибо за ответ. Я прокомментировал строку while (wait (NULL)! = - 1); и теперь, когда я запускаю программу, мой ubuntu выходит из системы автоматически. Кажется, мое приложение выдает SO. Как мне исправить? Я имею ограниченное знание этих вещей. Я был бы очень рад вашей помощи. ТКС! –
Если вы закомментируете цикл, родительскому процессу больше нечего делать после того, как он разворачивает всех детей, поэтому он завершает работу. – Barmar