简体   繁体   English

父进程终止后如何杀死所有子进程?

[英]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. 注意, SIGKILLSIGTERM信号可能需要父进程的某些特权。 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_Exitabort

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.

相关问题 如何在c中杀死父进程及其所有子进程? - how to kill the parent process and all its child processes in c? 在UNIX中杀死父进程的所有子进程的C / C ++程序? - C/C++ program to kill all child processes of a parent process in UNIX? 杀死父进程的所有子进程但让父进程保持活动状态 - Kill all child processes of a parent but leave the parent alive 如何被父进程杀死子进程? - How to kill a child process by the parent process? 如何在孩子完成之前杀死父进程? - How to kill parent process before the completion of the child? 程序的进程图清楚地显示了从创建到终止的父进程和子进程执行 - Process Graph for the program clearly showing the parent and child processes execution from creation to termination 父进程等待所有子进程完成后再继续 - Parent process waits for all child processes to finish before continuing 当父进程等待子进程终止时,子进程如何杀死父进程? - How can child kill parent process while parent process waits until child process to terminate? 从同一进程创建N个子进程,然后打印具有相关父进程的所有子进程的PID - Create N child processes from the same process then print PID of all child process with correlative parent process 父进程如何通过等待调用_exit的子进程获得终止状态 - How does parent process get the termination status through wait from a child process which calls _exit
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM