Below is an example of the Fork function in action. Below is also the output. My main question has to to do with the a fork is called how values are changed. So pid1,2 and 3 start off at 0 and get changed as the forks happen. Is this because each time a fork happens the values are copied to the child and the specific value gets changed in the parent? Basically how do values change with fork functions?
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
pid_t pid1, pid2, pid3;
pid1=0, pid2=0, pid3=0;
pid1= fork(); /* A */
if(pid1==0){
pid2=fork(); /* B */
pid3=fork(); /* C */
} else {
pid3=fork(); /* D */
if(pid3==0) {
pid2=fork(); /* E */
}
if((pid1 == 0)&&(pid2 == 0))
printf("Level 1\n");
if(pid1 !=0)
printf("Level 2\n");
if(pid2 !=0)
printf("Level 3\n");
if(pid3 !=0)
printf("Level 4\n");
return 0;
}
}
Then this is the execution.
----A----D--------- (pid1!=0, pid2==0(as initialized), pid3!=0, print "Level 2" and "Level 4")
| |
| +----E---- (pid1!=0, pid2!=0, pid3==0, print "Level 2" and "Level 3")
| |
| +---- (pid1!=0, pid2==0, pid3==0, print "Level 2")
|
+----B----C---- (pid1==0, pid2!=0, pid3!=0, print nothing)
| |
| +---- (pid1==0, pid2==0, pid3==0, print nothing)
|
+----C---- (pid1==0, pid2==0, pid3!=0, print nothing)
|
+---- (pid1==0, pid2==0, pid3==0, print nothing)
Ideally below is how I would like to see it explained as this way makes sense to me. The * are where my main confusion lies. When the child forks for example pid1 = fork();
that creates a process with all the values of the parent, but does it then pass up a value like lets say 1 to the parents pid1? Meaning the child would have pid 1=0, pid2=0 and pid3=0 and the parent then as pid1=2 and pid2 and 3 equal to 0?
fork() in C Fork system call is used for creating a new process, which is called child process, which runs concurrently with the process that makes the fork() call (parent process). After a new child process is created, both processes will execute the next instruction following the fork() system call.
fork() is how you create new processes in Unix. When you call fork , you're creating a copy of your own process that has its own address space. This allows multiple tasks to run independently of one another as though they each had the full memory of the machine to themselves.
The C library defines fork() . It is the UNIX/Linux-specific system calls to create a process, on linux etc.
fork starts a new process which is a copy of the one that calls it, while exec replaces the current process image with another (different) one. Both parent and child processes are executed simultaneously in case of fork() while Control never returns to the original program unless there is an exec() error.
System call fork() is used to create processes. It takes no arguments and returns a process ID. The purpose of fork() is to create a new process, which becomes the child process of the caller. After a new child process is created, both processes will execute the next instruction following the fork() system call. Therefore, we have to distinguish the parent from the child. This can be done by testing the returned value of fork()
Fork is a system call and you shouldnt think of it as a normal C function. When a fork() occurs you effectively create two new processes with their own address space.Variable that are initialized before the fork() call store the same values in both the address space. However values modified within the address space of either of the process remain unaffected in other process one of which is parent and the other is child. So if,
pid=fork();
If in the subsequent blocks of code you check the value of pid.Both processes run for the entire length of your code. So how do we distinguish them. Again Fork is a system call and here is difference.Inside the newly created child process pid will store 0 while in the parent process it would store a positive value.A negative value inside pid indicates a fork error.
When we test the value of pid to find whether it is equal to zero or greater than it we are effectively finding out whether we are in the child process or the parent process.
Read more about Fork
int a = fork();
Creates a duplicate process "clone?", which shares the execution stack. The difference between the parent and the child is the return value of the function.
The child getting 0 returned, and the parent getting the new pid.
Each time the addresses and the values of the stack variables are copied. The execution continues at the point it already got to in the code.
At each fork
, only one value is modified - the return value from fork
.
First a link to some documentation of fork()
http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html
The pid is provided by the kernel. Every time the kernel create a new process it will increase the internal pid counter and assign the new process this new unique pid and also make sure there are no duplicates. Once the pid reaches some high number it will wrap and start over again.
So you never know what pid you will get from fork(), only that the parent will keep it's unique pid and that fork will make sure that the child process will have a new unique pid. This is stated in the documentation provided above.
If you continue reading the documentation you will see that fork() return 0 for the child process and the new unique pid of the child will be returned to the parent. If the child want to know it's own new pid you will have to query for it using getpid().
pid_t pid = fork()
if(pid == 0) {
printf("this is a child: my new unique pid is %d\n", getpid());
} else {
printf("this is the parent: my pid is %d and I have a child with pid %d \n", getpid(), pid);
}
and below is some inline comments on your code
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
pid_t pid1, pid2, pid3;
pid1=0, pid2=0, pid3=0;
pid1= fork(); /* A */
if(pid1 == 0){
/* This is child A */
pid2=fork(); /* B */
pid3=fork(); /* C */
} else {
/* This is parent A */
/* Child B and C will never reach this code */
pid3=fork(); /* D */
if(pid3==0) {
/* This is child D fork'ed from parent A */
pid2=fork(); /* E */
}
if((pid1 == 0)&&(pid2 == 0)) {
/* pid1 will never be 0 here so this is dead code */
printf("Level 1\n");
}
if(pid1 !=0) {
/* This is always true for both parent and child E */
printf("Level 2\n");
}
if(pid2 !=0) {
/* This is parent E (same as parent A) */
printf("Level 3\n");
}
if(pid3 !=0) {
/* This is parent D (same as parent A) */
printf("Level 4\n");
}
}
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With