0

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;
}
}
Pierre
  • 1,162
  • 12
  • 29
shen
  • 17
  • 8
  • 1
    Possible duplicate of [How to make child process die after parent exits?](http://stackoverflow.com/questions/284325/how-to-make-child-process-die-after-parent-exits) – Hayt Oct 07 '16 at 13:36
  • or do you mean the parent process is still running? – Hayt Oct 07 '16 at 13:36
  • yes, parent returns main, and child die – shen Oct 07 '16 at 13:37
  • "return main" would mean the parent process terminates itself. Then this would be a duplicate. – Hayt Oct 07 '16 at 13:38
  • I don't really know if parent would die if it return – shen Oct 07 '16 at 13:39
  • 1
    well that is kind of important here for the answer if the parent process dies or not. – Hayt Oct 07 '16 at 13:40
  • I think it would die according to your comment. But I just want to know how to make it on my case – shen Oct 07 '16 at 13:42
  • Maybe you should check if you process is still running or not. – Hayt Oct 07 '16 at 13:44
  • I use getppid() to keep checking in the child, it is not 1. but I don't understand why not. – shen Oct 07 '16 at 13:54
  • `getpid` gives you the pid of the current process... So this will be whatever pid your child has. Most likely not 1 though. – Hayt Oct 07 '16 at 13:57
  • 1
    Compared to things like creation of a process, or death of a process, returning from a function is a very minor event. Events on that scale just aren't noticeable outside the process where they occur. –  Oct 07 '16 at 14:03
  • This is getppid not pid, but your answer is awesome. – shen Oct 07 '16 at 14:11
  • @shen ah sorry my bad. Explanation is, your parent had maybe another parent (who was not process 1) and this has now become the new parent. explanation here: http://unix.stackexchange.com/questions/194182/orphan-processs-parent-id-is-not-1-when-parent-process-executed-from-gnome-term – Hayt Oct 07 '16 at 14:14

2 Answers2

0

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.

Hayt
  • 5,210
  • 30
  • 37
  • @shen signals are a common way to communicate between processes in Linux. You should read up about them. It helps a lot – Hayt Oct 07 '16 at 14:11
0

You say you want the child to

wait main process to return to its main function

. That's a bit hard to follow, but I think you mean that you want the child to wait until its parent process returns to the caller of the function in which the fork() was performed. It's unclear whether the caller is expected to be that process's main() function, but that doesn't actually make any difference.

However, no function can exert direct control over what happens when it returns. The best it can do is perform some action immediately before it returns.

Moreover, since the function you present is not main(), there is no reason to suppose that the parent process terminates when it returns from that function. Until it does terminate, the child process will remain its child, and therefore will not observe itself being inherited by process 1.

Since the program in fact is not working as you expect, I suppose that the parent process indeed is not terminating, so you need a different approach. Specifically, you need some form or other of inter-process communication (IPC). There are several flavors to choose from, and as a bonus, many of them do not require the child to busy-wait. Among the more likely options are

  • a process-shared mutex or semaphore
  • a signal
  • a pipe

Of those, I'd recommend the last. It could look like this:

void otherplacecall(){
    int pfd[2];
    pid_t pid;
    char c;

    if (pipe(pfd)) {
        // ... handle error in pipe() ...
        return;
    }
    switch(pid = fork()) {
        case -1:
            // (parent) ... handle error in fork() ...
            break;

        case 0:
            // child
            printf("child: my process id is %d\n", (int) pid);
            if (close(pfd[1])) {
                // ... handle error in close() ...
                _Exit(1);
            }
            if (read(pfd[0], &c, 1) < 0) {
                // ... handle error in read() ...
            }
            puts("child: received the signal to proceed");
            puts("child: I terminating");
            _Exit(0);

        default:
            // parent
            close(pfd[0]);
            puts("parent: my son, take care of yourself");
            close(pfd[1]);  // this will cause the child's read() to return
    }
}

Among the characteristics of this approach is that if the parent does terminate then its copies of the pipe ends will be closed, even if it does not close them explicitly, so the child will then proceed. That won't happen under some other circumstances, such as if the child is awaiting a signal, and the parent dies before sending it.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157