Understanding the fork() command Posix API - c

#include<iostream>
#include<unistd.h>
#include<stdio.h>
using namespace std;
int main()
{
fork();
fork();
fork();
fork();
printf("*"); /*This prints 16 stars*/
return 0;
}
When working with fork(), why does it print 16 *'s?
I understand that fork() generates a new
child process that both execute the same process which would explain why one fork generates 2 stars but, with four forks it prints 16 which I can see that it doubles with each fork().
But I am not understanding why. Is each fork executing the functions and parameters below it?

Because the first fork will split into two process, the second fork() call will be called by those two processes, splitting those two processes into 4. This will continue until all the fork() calls have been called in each process. So you end up having 2^4 = 16 calls to printf("*")
In the "diagram" each bar represents the number of processes that are executing when the function is called. So the function is executed as many times as there are bars.
| fork() // The first processes creates a second (2 total)
| fork() | // Those 2 processes start 2 more (4 total)
|| fork() || // Those 4 processes start 4 more (8 total)
|||| fork() |||| // Those 8 processes start 8 more (16 total)
|||||||| printf() |||||||| // resulting in 16 calls to printf()
Is each fork executing the functions and parameters below it?
Yes, as you can see from the diagram, when a process forks the created process (and the one that created it) continues execution on the next instruction after the fork.

When you call fork(), it create a new process. You duplicate your application, and then the 2 applications continues to run and execute new instructions after the fork() call
printf("i'm the main thread\n");
fork();
printf("i'm executed 2 times\n");
fork(); //this fork is so executed 2 times, so 2 new processes, so 4 processes for all
printf("i'm excecuted 4 times\n");
fork(); //this fork is executed 4 times to ! So you have now 8 processes;
// and etc ..
fork(); //this fork is executed 8 times, 16 process now !
printf("*"); // executed 16 times
The new processes share all memory before the fork(), old changed states are for the current thread.
if you want to do anothers things depending the process :
pid_t p;
int i = 1;
p = fork();
if(p == 0)
{
printf("I'm the child\n");
i = 2;
exit(0); //end the child process
}
printf("i'm the main process\n");
printf("%d\n", i); //print 1

Related

How many processes would be created from fork() in this code?

This is a question from one of my tasks and I'm having some confusion with it.
int main()
{
printf("line\n");
pid_t pid = fork();
fork();
fork();
if(pid == 0)
fork();
fork();
printf("line\n");
return 0;
}
How many processes would be created from the execution of the code?
From executing the code, it would generate 28 lines of output and just not sure how to find the amount of processes created in this statement.
There will be a total of 24 processes. Here is how.
After the first fork() there are two processes. In one of them pid == 0; in the other process pid != 0.
After second fork, there are 4 processes (half of them have pid == 0).
After third fork, there are 8 processes (and half of them have pid == 0).
The fourth fork statement is executed only by those processes where pid == 0. So 4 processes will execute fork (and turn into 8 processes). The other 4 processes will not execute fork and will remain 4. Alltogether we have 8+4=12 processes.
Finally, another fork turns our 12 processes into 24.
How many threads would be created from the execution of the code?
Now is the question of semantics. Do you say that processes are not threads, and so 0 threads are created? Do you say that out of 24 processes, the first one is the original process and not created by this code, so a total of 23 processes are created? This is a question of semantics, not of software, so we can't help you with this.
Number of lines printed
The first printf is executed by the original process only (since it has not forked yet). The second printf is executed by all 24 processes (just before each process terminates). So a total of 25 lines is printed.
As above, 24 leaves produce.So 24 processes produce finally.And before your first fork, "line" will be printed one time. After you fork, because of 24 processes, 24 "line" will be printed. So you will have 25 "line".

How many processes this code going to generate?

I am not sure how many processes going to be created in this program? I suppose there is going to be created three child process in a while loop. Then, each child process is going to fork two times which means there are going to be two child process plus the one created by that child process is also going to fork and there is going to be 4 child process for each state. In total, there are 12 processes. Is that true?
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
pid_t childpid;
int i=0;
while((childpid>0) && (i<3))
{
childpid=fork();
i++;
}
if(childpid==0){
fork();
fork();
}
exit(0);
}
The total number of processes is 13
while((childpid>0) && (i<3))
will only execute for the parent since the fork() system call returns the pid of the child to the parent process and a 0 to the child process.
Thus the while loop will generate 3 child processes with the childpid variable value 0, and the main parent process which now has the childpid variable value equal to that of the last forked child.
Total processes till now 4
For the condition
if(childpid==0){
fork();
fork();
}
each child process from before spawns 1 child in the first fork call. The second fork will spawn another two new processes from the two proceeses of the first fork. So for each child process we will have spawned processes a total of 3 new processes.
Thus for th 3 child processes from the while loop, we will generate 9 new processes.
So total number of processes would be 4 + 9 = 13

Could someone explain how fork works?

I don't really understand how fork() works.I understand examples with one fork,but when there are more than one call I don't.I have an example like this and it prints 4 lines of hello, how many processes are created?
int main(void)
{
fork();
fork();
printf("hello\n");
return 0;
}
After fork() call, both processes (original and spawned) continue to execute from next line of code. So both processes execute second fork() instruction, so in the end you have 4 processes. Hence you see 4 instances of "hello" lines printed.
One picture is worth a thousand words:
The fork() syscall essentially creates a "clone" of the process executing it. Both "clones" run almost identically (except for the return value of fork()).
The first call to fork() is executed by one process (let's call that one "P"), which creates a second process "C". Now there are two processes, which both execute the second line in your main() function. So both processes, P and C, create a new process. This is why you end up with a total of 4 processes, all of which print "hello" exactly once.
The following example might make that behaviour a bit clearer:
int main() {
printf("process %d: start\n", getpid());
int r1 = fork();
printf("process %d: first fork() returned %d\n", getpid(), r1);
int r2 = fork();
printf("process %d: second fork() returned %d\n", getpid(), r2);
}
On my system, it outputs the following:
process 12953: start
process 12953: first fork() returned 12954
process 12954: first fork() returned 0
process 12953: second fork() returned 12955
process 12955: second fork() returned 0
process 12954: second fork() returned 12956
process 12956: second fork() returned 0

How many processes are created with these fork() statements?

I believe that this creates 24 processes; however, I need verification. These questions often stump me. Thanks for the help!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
pid_t pid = fork();
pid = fork();
pid = fork();
if (pid == 0)
{
fork();
}
fork();
return 0;
}
It's fairly easy to reason through this. The fork call creates an additional process every time that it's executed. The call returns 0 in the new (child) process and the process id of the child (not zero) in the original (parent) process.
pid_t pid = fork(); // fork #1
pid = fork(); // fork #2
pid = fork(); // fork #3
if (pid == 0)
{
fork(); // fork #4
}
fork(); // fork #5
Fork #1 creates an additional processes. You now have two processes.
Fork #2 is executed by two processes, creating two processes, for a total of four.
Fork #3 is executed by four processes, creating four processes, for a total of eight. Half of those have pid==0 and half have pid != 0
Fork #4 is executed by half of the processes created by fork #3 (so, four of them). This creates four additional processes. You now have twelve processes.
Fork #5 is executed by all twelve of the remaining processes, creating twelve more processes; you now have twenty-four.
Calculate in this way :
Start with 1(Main Process) and for every fork make it twice if fork is not inside if(pid == 0) else add 1/2 of current process to current number of process.
In your code:
1P
Got #1 fork() so double up current number of processes. Now new number of process 2P
Got #2 fork() so double up current number of processes. Now new number of process 4P
Got #3 fork() so double up current number of processes. Now new number of process 8P
Got #4 fork() but wait it's in if condition so (8+4 = 12)P
Got #5 fork() so double up the current number of processes. Now new number of process 24P
You are correct. It's 24. Just compiled and ran it w/printf before the final return statement. Got 24 lines of output.
This statement have 24+ child process.
Each invocation of fork() results in two processes, the child and the parent. Thus the first fork results in two processes. The second fork() is reached by those two processes, yielding four processes. The final fork() is reached by those four, netting eight processes more. All but one of these processes (the original) is a child of at least one of the forks.

Create a process and tell it to sleep?

What's the right way to tell a specific process to sleep?
I don't fully understand how to control the different processes I create..
I'm trying to make two processes that sleep for 2 and 3 seconds. When process 1 has slept for 2 seconds, and process 2 is still sleeping I want process 3 to start sleeping. But how do I tell a process to sleep? Or don't I?
int main(void)
{
pid_t p1 = fork();
pid_t p2 = fork();
pid_t p3 = fork();
//make p1 sleep(2) and p2 sleep(3)
waitpid(p1, NULL, 0); //waiting for p1 to terminate
//make p3 sleep(2);
}
As you can see I don't understand how to handle processes, or what they really are. I kind of see them as objects, but I'm guessing that's wrong.. I've tried reading some stuff about it, but they are all over 9000 pages PDF's.. A simple explanation of what I should see them as would be appreciated. And yes, this is school-material, but no, it's not an assignment.
Start with man fork which is slightly shorter than 9000 pages. The main thing is that successful fork returns two times: it returns 0 to the child process and the child's PID to the parent process. It's typically used like this:
pid_t pid = fork();
if (pid<0) { /* error while forking */
};
if (!pid) { /* code for child */
play();
whine();
sleep();
exit(0);
} else { /* code for parent */
grunt();
waitpid(...);
}
You don't normally tell the child process to do this and that, you just add code doing it to the appropriate if branch.
In your example, if all forks are successful, you end up with 8 processes:
First fork creates a new process, p1 gets 0 in the new process and some pid in the parent.
Second fork is called both in the original parent and in the child, adding 2 processes to the picture.
p2 gets 0 in all "grandchildren" and two different pids in 2 processes existing before step 2.
Third fork is called in four different processes, adding four other processes to the picture.
You could send it a SIGSTOP and then a SIGCONT I think.
kill(p1, SIGSTOP);
Alternatively and more sanely, since you're only forking and thus have complete controll over the code, you could handle the paths:
if (in_child_1)
sleep(..);
As a side note, in your code more processes are created than you expect. The thing is once p1 is created it starts executing from that point, in parallel with its parent. And so on.

Resources