Why isn't the child PID always parent+1 in fork()?
Issue: I noticed that the difference between the child and parent process' PIDs was different while running in Vim vs regular terminal.
My code:
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t child_pid; //pid_t is a data type used to represent a process id
child_pid = fork();
printf("\n\nProcess: my PID is %d, and my parent is %d", getpid(), getppid());
if(child_pid 0)
{
printf("\nChild's pid = %d",getpid());
}
else if(child_pid > 0)
{
printf("\nParent Pid %d",getpid());
}
else
{
printf("fork failed");
return 1;
}
return 0;
}
Inside vim:
Notice that difference between the parent and child ID is 6 -- not 1, as I had expected.
# (1st time execution)
Process: my PID is 10362, and my parent is 10164
Parent Pid 10368
Process: my PID is 10368, and my parent is 10362
Child's pid = 10368
Press ENTER or type command to continue
# (2nd time execution)
Process: my PID is 10515, and my parent is 10164
Parent Pid 10515
Process: my PID is 10521, and my parent is 10515
Child's pid = 10521
Press ENTER or type command to continue
Inside terminal
anu@laptop:~/anu/programming/systems_progg$ gcc fork.c -o out && ./out
Process: my PID is 11057, and my parent is 4872
Parent Pid 11057
Process: my PID is 11058, and my parent is 11057
Child's pid = 11058
Why difference of 6 each time?
My hypothesis:
Vim IDE must be creating 5 helper processes each time in between the span of creation of parent process and when I called fork.
In order to test this, I tried tracing with strace inside vim.
strace -e trace=fork ./out
//note: ./out is my compiled binary for the C code.
Output:
Process: my PID is 15365, and my parent is 15364
Child's pid = 15365
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=15365, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
Process: my PID is 15364, and my parent is 15361
Parent Pid 15364+++ exited with 0 +++
Note that the difference betweent the child and the parent was 1 this time. Why?
The reason the +6 difference was constant whenever I run the program inside vim is because vim must be creating processes while running the command inside it, invoking shell, gcc, etc. This chain must be consistent each time I run it, so the difference was constant.
So, each time, the execution chain while running in vim must be like:
vim -> shell -> gcc -> ./out -> helper process -> MY FORK CHILD
But when I traced it with strace, the execution flow should have looked somewhat like this:
shell -> strace -> ./out -> MY FORK CHILD
strace changes scheduling timing, signal delivery timing, and CPU usage patterns.
So, strace must have altered the timing!
This hypothesis was unfortunately wrong
My observation of the difference of child and parent process being 6 was consistent was true at the time I executed.
However, after rebooting my laptop and running the code again, this is what I got:
Process: my PID is 10970, and my parent is 10959
Parent Pid 10970
Process: my PID is 10971, and my parent is 10970
Child's pid = 10971
The difference between child and parent's pid was 1!
After looking into this, I learnt that PIDs are allocated from the global system-wide PID counter.
The PID is assigned at the time of fork(), not when the child process runs.
This means that when the my process calls
child_pid = fork();
then it is assigned the next available PID at that exact moment.
If there are no processess in between then only the child's PID is parent+1
Thus, the PID number of the child is fully dependent on the global system wide PID counter. The number it gets assigned at that time determines the PID gap.
Once fork() is called, the order of execution is not guaranteed. Sometimes parent prints first, sometimes the child.
I have written about this in the post [link]
The theory about strace altering timing isn't valid here either. strace did change the execution environment, but it didnt affect the PID number gap.
Conclusion: The difference between parent and the child process PID is not always one. There can be system processes created between that time, and the order of execution of the forks is not always guaranteed.
Comments
Post a Comment