Vincenzo Cosi
Vincenzo Cosi

Reputation: 187

Why does my forked process's parent pid differ from the parent's own pid?

I'm trying to understand how some of unistd.h functions work. This is the code I wrote:

#include <stdlib.h>
#include <unistd.h>

int main(){
  pid_t pid;
  pid=fork();
  switch(pid) {
  case 0: //child
     printf("case 0:\nchild %d\nparent %d\n", getpid(), getppid());
     break;
  default: //parent
     printf("default:\npid(child) %d\nparent %d\n", pid, getpid());
     break;
  }
}

I think that the parent pid obtained by the getppid() in the case 0 and the parent pid obtained by the getpid() in the default case should be the same, but this is the output of my little program:

default:
pid(child) 29208
parent 29207

Process returned 0 (0x0)   execution time : 0.001s
Press ENTER to continue.
case 0:
child 29208
parent 1017

Why are they different? (29207 in a case and 1017 in the other)

Upvotes: 2

Views: 1090

Answers (2)

gonczor
gonczor

Reputation: 4136

You should slow down execution. AS you can see in you terminal child is executed after parent has finished. In this case it becomes an orphan and its PID is reassigned to different process. I do not know whether this works same on Linux, but on my Mac it was reassigned to process 1. So add sleep() before each parent's printf().

EDIT

I've compiled (compiled with llvm-gcc) and run your code before adding sleep:

 $  ./test
default:
pid(child) 2688
parent 2687
case 0:
child 2688
parent 1

And afterwards:

 $  ./test 
default:
pid(child) 2780
parent 2779
case 0:
child 2780
parent 2779

EDIT2

Since putting sleep() in child's PID solves nothing I changed the suggestion as to where it should be placed.

EDIT3

Since it is my answer that got accepted not Toby's which is way better, it is worth mentioning that proper synchronization mechanism would be making use of wait() function.

Upvotes: 3

Toby Speight
Toby Speight

Reputation: 30762

If the parent does not wait() for the child, it may exit before the child calls getppid(). If you want the parent to still exist and be the parent, you can ensure this by making it wait:

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
    const pid_t pid = fork();
    switch (pid) {
    case 0:
        printf("in child: me: %d; parent %d\n", getpid(), getppid());
        break;
    default: //parent
        printf("in parent: child: %d; me %d\n", pid, getpid());
        wait(NULL);
        break;
    }
}

(For your convenience, I've also added the headers you forgot to include - that's a sign that you haven't enabled sufficient warnings in your compilation).

Upvotes: 2

Related Questions