Search code examples
cforkglibc

How can I make child waiting parents to return (not exit) and then suicide?


I want to write such a function, which is called from other place. Which use fork to make a child and wait main process to return to its main function. I tried this method and also tried to set one flag to tell child parents return. But they are all not correct, and I have know the reason. I just want to know how can I make this point? Thanks!

void otherplacecall(){
fpid=fork();
if (fpid == 0) {
    printf("i am the child process, my process id is %d\n",getpid());
    while(getppid()!=1){printf("waiting\n");sleep(1);}
    if(getppid()==1){
        printf("father die!\n");
        printf("I am dying\n");
        exit(0);
        }
    }


else {
    printf("in the parents!, my process id is%d\n",getpid());
    printf("my son take care of yourself\n");
    return 1;
}
}

Solution

  • Assuming your parent process does not terminate, you have to manually send a signal to the child.

    Here is how to set this up:

    int run = 1;
    void OnSigUsr1()
    {
        run = 0;
    }
    
    ///....
    signal(SIGUSR1, OnSigUsr1);
    pid = fork();
    if(pid == 0)
    { //we are the child
        //loop until SIGUSR1 comes in
        while(run == 1) p_sleep(1000);
    }
    else
    { //we are the parent
        //send the SIGUSR1 signal to child
        kill(pid,SIGUSR1);
    }
    

    When the process now gets the signal SIGUSR1 the function OnSigUsr1 is called. In this you can set some global variable to false.

    The kill command does not kill the child but sends a signal to it (the name may be misleading).

    When your parent is terminating by itself though you don't need to manually send a signal but can tell Linux to send you a signal when the parent dies.

    This can be done by adding

    prctl(PR_SET_PDEATHSIG, SIGUSR1);
    

    Now your child processes get the signal on "death" of the parent.

    If you don't need any extra handling but just the child to terminate you can "skip" the custom signal handling and send SIGTERM instead of SIGUSR1. By default this will end the process.


    You should read about signals a bit this will help with understanding the code more.