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

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".

Related

Unique processes and threads in c [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
For the program below:
int main() {
Pid_t pid1, pid2;
Pid1 = fork();
pid2 = fork();
if (pid1 == 0) { /* child process */
thread_create(. . .);
}
if (pid2 == 0) { /* child process */
pthread_create(. . .);
}
fork();
}
a.How many unique processes are created?
b. How many unique threads are created?
Our class has been discussing this for two days. We are told that it is 2 unique threads. However when I replace the pthread_create with a print I am getting more than two. I get this output
Thread 2: 1855 0
Thread 1: 0 1859
Thread 1: 0 0
Thread 2: 0 0
Where Thread 1/2 shows the if statments and pid1 pid2 is printed.
So why is it 2? Can you provide an explanation we can show in class?
The first fork creates a second process from your first process. But the second fork is not guarded by checking the PID, so this fork happens in both processes, resulting in a total of 4 processes. The final fork at the end will then result in 8 processes.
So, when you read the if statements, you have 4 processes. Lets examine the pid values in these processes:
Process 1: Pid1=0, Pid2=0
Process 2: Pid1=0, Pid2=non-0
Process 3: Pid1=non-0, Pid2=0
Process 4: Pid1=non-0, Pid2=non-0
You will see that process 1 will now create 2 threads. Process 2 will create 1 thread, process 3 will create 1 thread, and process 4 will create no threads.
So why is it 2?
As we have seen, it is not. 4 new threads are created (for a total of 12 threads if we included the main thread of each process).
I'm not sure what a "unique" thread is supposed to be in this context, but the number of processes created here is 8; We start with one process, the first fork creates another. Both of those hit the second fork, which creates 2 more processes, and finally all of those 4 hit the last fork making for 8 processes total.
The first pthread_create is hit by the second (first child of the first) process and the child of the second process, whereas the second pthread_create is hit by the child of the second process and the second child of the first process (be very skeptical about this paragraph, I got this mixed up in my head several times so I can see why you'd struggle with this).
So depending on what exactly you're counting, there are 8 "main" threads, 4 "auxiliary" threads or 12 threads total. Not sure how you're supposed to come up with 2, other than the trivial fact that there are 2 calls to pthread_create in the source code.
If you have a very particular definition of "unique thread" that would change this, please edit your answer to include it.
You start with one process, call it PROCESS_A.
After the first fork call you have two processes, PROCESS_A (pid1 > 0) and PROCESS_B (pid1 = 0).
Both PROCESS_A and PROCESS_B then fork again, producing (in total) PROCESS_A, PROCESS_B, PROCESS_C, and PROCESS_D, so we end up with:
First fork situation:
PROCESS_A (pid1 > 0, pid2 > 0) is the parent process of B.
PROCESS_B (pid1 = 0, pid2 > 0) is a child of PROCESS_A (pid1 > 0)
Second fork situation:
PROCESS_C (pid1 > 0 (copied from A), pid2 = 0) is a child of PROCESS_A (pid2 > 0)
PROCESS_D (pid1 = 0 (copied from B), pid2 = 0) is a child of PROCESS_B (pid2 > 0).
Thus, in terms of thread creation:
PROCESS_A doesn't create either thread, because both pid1 and pid2 are non-zero in PROCESS_A.
PROCESS_B creates the first thread but not the second.
PROCESS_C creates the second thread but not the first.
PROCESS_D creates both threads.
So by my count four threads are created.
The final fork call is a red herring. A new process is created, true, but it immediately terminates as there's no code following the last fork.

Working of fork() system call(C program)

When I run this code, it prints "hello world" 20 times. As per my understanding it should be print it 32 times. Also, the newline gets printed differently with each run. I don't understand this. Please help.
int
main(int argc, char** argv){
if(fork() || fork())
fork();
if(fork() && fork())
fork();
printf("\nhello world");
return 0;
}
To understand you will have to disect both constructs. First the construct
if( fork() || fork() )
fork();
or written in another way by unfolding the short-circuit or:
if( !fork() )
if( !fork() )
goto not_taken;
fork();
not_taken:
or without goto's
if( !fork() ) {
if( fork() )
fork();
}
else
fork();
will five-fold the number of processes. This is because first the original process forks, then in the child as the fork will return zero it will fork again (short-circuit or). Then if any of these returned non-zero (that is the parent of the fork) it will fork again - this happens to be done in the parent process and it's child. That is the forks in the conditions will be called once and the last fork will be run once.
Now for the second construct:
if( fork() && fork() )
fork();
or with unfolding short-circuit and:
if( fork() )
if( fork() )
fork();
the process count will four-fold. The reason is that first fork will be run in the parent process and if that returns non-zero (ie the parent process) the second fork will be called and if that to returns non-zero the last will. So here all three forks are called in the original process - which means that it's called three times.
So first construct will make them five processes and the second will then for each process create three more. That means we will have 5*4 processes.
The reason you don't get consistent newlines is probably most due to printf buffering. The printf will only immediately print out a newline, and then write the rest of the data when it terminates, this means that they print the string in two step. We have 20 processes that first prints a newline and then prints "hello world" concurrently - the order between what the different processes prints cannot be guaranteed.
A minor possibility is the very fact that the actual printout aren't required to be atomic. That is one process may write "hell", and then a second which already written "hello " gets to write which may be "world" - which would result in "hellworld" instead.
Let's count how many times each fork is called. In this block there are 3 forks:
if(fork() || fork())
fork();
The 1st fork is called 1 time, by the first process.
The 2nd fork is called only 1 time, by the second process. (first process doesn't reach it)
The 3rd fork is called 2 times, by both first and second processes.
So, at this point you already have 5 processes.
For this block there are another 3 forks:
if(fork() && fork())
fork();
The 1st fork is called 1x 5 times. Here, the forked child process goes to printf directly.
The 2nd fork is called 1x 5 times. Still, the forked child process goes to printf.
The 3rd fork is called 1x 5 times.
So you have 20 in total.
This is much easier if you evaluate the two if constructs separately. Count the number of processes created in the first and multiply it by the number created in the second. The result is the total number of processes and the times the printf call is called.
(We are assuming fork calls will not fail.)
The first if statement is shows by this handy chart, where columns are forks, rows are processes.
forks - f1, f2, f3
processes - c0, c1, ... ,c4
xN - marks the creation of a process where N is the index of the created process
. - marks the process creation
_ - process exists and does nothing
(no character means the process doesn't exist at that point)
f1 f2 f3
c0 _ x1 _ x2 _
c1 . x3 x4 _
c2 . _
c3 . _ _
c4 . _
At this point 5 processes exist, 4 additional were created. The next chart shows the second if statement, but only for one process:
f1 f2 f3
c0 _ x1 x2 x3 _
c1 . _ _ _
c2 . _ _
c3 . _
This if statement, creates 3 additional processes, so 4 exist. But remember we had 5 processes before, not just one. So both if statements together create 5 x 4 processes, 20 in total.

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

Understanding the fork() command Posix API

#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

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.

Resources