[英]How to kill all child processes after parent process termination?
I can kill a child process by the parent process. 我可以通过父进程杀死一个子进程。 But what happen if a parent process has more than one child processes?
但是,如果一个父进程有多个子进程,该怎么办?
For example in below code , there are one parent process and 6 child processes. 例如,在下面的代码中,有一个父进程和6个子进程。 How to kill the other six child processes immediately after the parent process termination?
父进程终止后,如何立即杀死其他六个子进程?
If you run this code, parent is terminated after 5 seconds.After that child process are terminated after another 5 seconds(totally 10 seconds). 如果运行此代码,父进程将在5秒钟后终止。子进程在另外5秒钟(总共10秒钟)后终止。
But I want to kill 6 child processes immediately after the parent process termination.So parent and 6 child process should be terminated after 5 seconds. 但是我想在父进程终止后立即杀死6个子进程,因此父级和6个子进程应该在5秒后终止。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
for(int i=0;i<6;i++) // loop will run 6 times(there are 6 child processes.)
{
if(fork() == 0)
{
printf("Started [son] pid %d from [parent] pid %d\n",getpid(),getppid());
sleep(10); //child waits 10 seconds,then it exitted.
printf("Exitted [son] pid %d from [parent] pid %d\n",getpid(),getppid());
exit(0);
}
}
//parent
sleep(5); //parent will wait 5 seconds than it will exit
printf("Parent terminated\n");
exit(0); //parent terminated.(how can I exit the the other 6 child processes too?)
}
On Linux, you can use prctl
to request to be informed about the death of your parent by means of a signal (error-checking skipped). 在Linux上,您可以使用
prctl
请求通过信号通知您父母的死亡(跳过错误检查)。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/prctl.h> //<<<<<<<<
#include <signal.h> //<<<<<<<<
int main()
{
for(int i=0;i<6;i++) // loop will run 6 times(there are 6 child processes.)
{
if(fork() == 0)
{
prctl(PR_SET_PDEATHSIG, SIGTERM); //<<<<<<
printf("Started [son] pid %d from [parent] pid %d\n",getpid(),getppid());
sleep(2);
printf("Exitted [son] pid %d from [parent] pid %d\n",getpid(),getppid());
exit(0);
}
}
//parent
sleep(1);
printf("Parent terminated\n");
exit(0);
//<<< Linux auto-sends the deathsignal to all children
}
For a POSIX-compliant solution that doesn't require the parent process to explicitly kill its children when it dies, you can use async-IO pipes. 对于不需要父进程在死时显式杀死其子进程的POSIX兼容解决方案,可以使用async-IO管道。
Async-IO relies on signals being sent on filedescriptor events. 异步IO依赖于在文件描述符事件上发送的信号。 In this case you can get notified of a close-event caused by the kernel autoclosing the filedescriptors of a dying process just as long as you make sure the autoclose closes the last reference to the pipe-end file (error-checking skipped):
在这种情况下,只要确保自动关闭关闭对管道端文件的最后引用(跳过错误检查),就可以通知内核自动关闭即将死去的进程的文件描述符而导致的关闭事件:
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/ioctl.h>
int main()
{
int pipes[6][2];
for(int i=0;i<6;i++) // loop will run 6 times(there are 6 child processes.)
{
pipe(pipes[i]); //create a pipe
if(fork() == 0)
{
//get notified on an event on the read-end (we're aiming for the EOF event)
fcntl(pipes[i][0],F_SETOWN,getpid());
ioctl(pipes[i][0], FIOASYNC, &(int){1});
for(int j=0; j<=i; j++) close(pipes[j][1]); //close all write-end ends so the refcount is 1 and the parent has the last ref
printf("Started [son] pid %d from [parent] pid %d\n",getpid(),getppid());
sleep(2);
printf("Exitted [son] pid %d from [parent] pid %d\n",getpid(),getppid());
exit(0);
}
}
//parent
sleep(1);
printf("Parent terminated\n");
exit(0);
//<<<this closes all the last write ends of the pipes and so the children will get notified with a signal
//the signal is SIGIO by default, whose default disposition is to kill the process (this can be changed by fcntl(fd,F_SETSIG,TheSignal))
}
Here's a probably more portable solution. 这是一个可能更便携的解决方案。
The fork(2)
system call will return the PID of your child processes, you can store the PIDs, and then you can use kill(2)
to send signal to the children and terminates them. fork(2)
系统调用将返回子进程的PID,可以存储PID,然后可以使用kill(2)
向子进程发送信号并终止它们。
Notice that SIGKILL
and SIGTERM
signal may require some privileges of the parent process. 注意,
SIGKILL
和SIGTERM
信号可能需要父进程的某些特权。 If it doesn't have such privileges, you can send a SIGCONT
to the child process, and modify the SIGCONT
signal handler in your child process. 如果没有这种特权,则可以将
SIGCONT
发送到子进程,并在子进程中修改SIGCONT
信号处理程序。
!!! !!! Warning sign
警告牌
From a signal handler using exit()
is not safe. 从信号处理程序使用
exit()
是不安全的。 I've just checked the manual man 7 signal
and found that it is not async safe. 我刚刚检查了手动
man 7 signal
,发现它不是异步安全的。 You can use _exit
, _Exit
or abort
您可以使用
_exit
, _Exit
或abort
Some pseudo code: 一些伪代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void* handler(int sig){
_exit(0);
}
int main()
{
pid_t children[6];
for(int i=0;i<6;i++) // loop will run 6 times(there are 6 child processes.)
{
if((children[i] = fork()) == 0)
{
signal(SIGCONT,handler);
printf("Started [son] pid %d from [parent] pid %d\n",getpid(),getppid());
sleep(10); //child waits 10 seconds,then it exitted.
printf("Exitted [son] pid %d from [parent] pid %d\n",getpid(),getppid());
exit(0);
}
}
//parent
sleep(5); //parent will wait 5 seconds than it will exit
for(int i=0;i<6;i++)
kill(children[I],SIGCONT);
printf("Parent terminated\n");
exit(0); //parent terminated.(how can I exit the the other 6 child processes too?)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.