Why does this code execute printf 8 times from forking? - c

Studying for finals, I got stuck on this problem. They ask how many times the following code executes printf:
#include "csapp.h"
void doit() {
Fork();
Fork();
printf("hello\n");
return;
}
int main()
{
doit();
printf("hello\n");
exit(0);
}
The solutions say that it printf executes 8 times, but I cannot figure out why. I've been trying to draw the picture of what's going on in the code, but my pictures make it seem like it only execute 4 times.

2 forks - Four processes. Each process has two printfs with hello (one in main and one in doit - hence 8.

Related

having problems with using fork() in C

Hello I'm trying to figure out how to use the fork method in C. (I'm new to C).
Following a tutorial I would expect the following code:
// 62-lab.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main() {
fork(); // 1st fork, output is one line (two expected)
//fork(); // 2nd fork, output is one line (four expected)
//fork(); // 3rd fork, output is two lines (eight expected)
printf("pid: %d\n", getpid());
return 0;
}
to give me two lines with the pids from the two processes. However I only get one line as an output.
Even stranger when I call the fork() method 3 times I get two lines as a result.
Edit
I also checked if the fork is successful with the following code:
int main() {
if (fork() >= 0) {
printf("pid: %d\n", getpid());
} else {
printf("Error while forking!");
}
return 0;
}
and the output is still only one line:
$ ./a.out
pid: 51582
$
Edit 2
So it seems the problem only appears when the stdout is connected to an eshell buffer in emacs. I ran the same code in other terminal emulators and there it worked as expected. This is odd, but for now I can bypass the problem by using another terminal emulator.
Any help is appreciated.

Number of print statements Fork() [duplicate]

So I have to find the output of this code which is using the fork() method. I thought the output was 5 "hello" s but instead I got 8. Why is that? This is the code:
#include "csapp.h"
void doit()
{
Fork();
Fork();
printf("hello\n");
return;
}
int main()
{
doit();
printf("hello\n");
exit(0);
}
Here's what your code is doing:
main->doit()->Fork()->Fork()->printf()->return->printf()->exit()
| |
| ----->printf()->return->printf()->exit()
|
----->Fork()->printf()->return->printf()->exit()
|
----->printf()->return->printf()->exit()
As you can see, you have a total of 8 calls to printf().
It would have been easier for you to see what was going on if you chose to print different strings in your main and doit functions.
Setting breakpoint on each printf() call is another effective strategy for figuring out these kinds of problems.
First you call fork and your one process forks into two. Then you call fork in each resulting process and you have a total of 4. Then the 4 processes print hello, return, and print hello again, for a total of 8 hellos.
You create process #1. Before printing anything, process #1 calls fork() and generates a clone that we will call process #2. Both processes #1 and #2 call fork() again, cloning into processes #3 and #4. Now you have 4 processes and each one of them will print hello twice. How many hello are printed?

Fork system call not exiting

I've run the following code :
#include <stdio.h>
#include <sys/types.h>
int main()
{
fork();
fork();
fork();
printf("hello\n");
return 0;
}
After printing the word "Hello" 8 times, the program is not exiting. What is the reason behind this?
This is an accidentally interesting way to calculate 2^3. The first fork makes the second fork happen twice and they each make the third fork happen twice and all 8 children run printf! The 8 processes do exit, but your prompt is lost in the noise.
As the commenters implied, you are fundamentally misunderstanding what fork() is and what it is doing. But along the way you made an interesting toy, so bravo!

why does this fork() out put produce 8 instead of 5?

So I have to find the output of this code which is using the fork() method. I thought the output was 5 "hello" s but instead I got 8. Why is that? This is the code:
#include "csapp.h"
void doit()
{
Fork();
Fork();
printf("hello\n");
return;
}
int main()
{
doit();
printf("hello\n");
exit(0);
}
Here's what your code is doing:
main->doit()->Fork()->Fork()->printf()->return->printf()->exit()
| |
| ----->printf()->return->printf()->exit()
|
----->Fork()->printf()->return->printf()->exit()
|
----->printf()->return->printf()->exit()
As you can see, you have a total of 8 calls to printf().
It would have been easier for you to see what was going on if you chose to print different strings in your main and doit functions.
Setting breakpoint on each printf() call is another effective strategy for figuring out these kinds of problems.
First you call fork and your one process forks into two. Then you call fork in each resulting process and you have a total of 4. Then the 4 processes print hello, return, and print hello again, for a total of 8 hellos.
You create process #1. Before printing anything, process #1 calls fork() and generates a clone that we will call process #2. Both processes #1 and #2 call fork() again, cloning into processes #3 and #4. Now you have 4 processes and each one of them will print hello twice. How many hello are printed?

How many times are executed the programs invoked by execl?

Can you help me with this?
How many times are executed the programs "exam" and "students" invoked by execl? I think the correct answer is 8 runtimes for program "exam" and 0 for "students", because in the two first forks will be created 3 child processes, after that in loop the first fork() will create more 4 processes, since the three children already created also will run this code, thereafter we have a exec that will replace the current code of the 7 processes created and of the actual program and run it(program "exam") 8 times. My reasoning is correct?
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main(){
int i;
pid_t
pid=fork();
pid=fork();
for(i=0;i<5;i++){
pid=fork();
execlp("exam","exam",NULL);
if(pid==0){
break;
}
}
execlp("students", "students","sistcomp",NULL);
return 0;
}
Theoretically, you are right. Let me draw a diagram to explain:
+---1 ...
|
+---+---2 ...
|
----+---+---3 ...
fork()|
+---4+---- execlp("exam","exam",NULL);
fork() |
+---- execlp("exam","exam",NULL);
^
after the first two fork()
you see, after 2 fork(), we get 4 process. Take the No.4 as an example, it enter for loop and fork() again, then we get another child process here, this child process and its father will exec execlp("exam","exam",NULL); as you see this will replace the current code.The same is true for No.1, No.2 and No.3.
So, it will be 8 runtimes for program "exam" and 0 for "students".
But, when you run this code, runtimes for program "exam" may be 7 or 6, it may be caused by Copy-on-write(I am not pretty sure about this)
PS:
It is a good practice to use execlp like this:
if (pid == 0)
execlp("exam","exam",NULL);
or
if (pid != 0)
execlp("exam","exam",NULL);

Resources