我试图在4个进程(3个孩子+ 1个父亲)之间处理信号SIGTERM和SIGUSR1,但我不知道为什么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;
}
答案 0 :(得分:0)
处理程序将由接收信号的进程执行。
要杀死孩子3,可以使用kill(child3,SIGKILL)
代替raise(SIGKILL);
。
在该程序的第一个信号中,处理程序将由父亲调用,因为父亲收到了第一个信号(SIGUSR1
),所以做raise(SIGKILL);
父亲正在自杀。
以下是整个代码:
#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",child1);
if(kill(child1,SIGKILL)==-1)
perror("Did not kill (1)");//kills child1
printf("The child2 %d is going to be killed later\n",child2);
if(kill(child2,SIGTERM)==-1)
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",child3);
//main(); //restart application
if(kill(child3,SIGKILL)==-1)
perror("Did not kill (3)");//kills child3. At this point all children have died.
}
}
if (signal==SIGTERM){
printf("The child2 %d is going to be killed now\n",getpid());
if(raise(SIGKILL)==-1)
perror("Did not kill (4)");//let the child2 goes through interrupt_handler
}
}
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("Sending user signal\n");
if(kill(getppid(), SIGUSR1)==-1)
perror("Did not kill (5)");//kills child3
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());
while(wait(NULL)!=-1);
printf("The father %d is going to die\n",getpid());
exit(0);
}