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
Related
I am learning fork() in Linux, and here is my program:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 int main(void){
5 int pid;
6 pid = fork();
7 if(pid < 0){
8 exit(1);
9 }
10 if(pid == 0){
11 fork();
12 fork();
13 printf("pid:%d ppid:%d\n",getpid(),getppid());
14 exit(0);
15 }
16 else{
17 printf("parent pid:%d ppid:%d\n",getpid(),getppid());
18 exit(0);
19 }
20
21 }
Sometimes it worked fine, with result like this:
./test1.out
parent pid:27596 ppid:21425
pid:27599 ppid:27597
pid:27597 ppid:27596
pid:27598 ppid:27597
pid:27600 ppid:27598
But the result was not consistent, more often than not it worked like this:
parent pid:27566 ppid:21425
pid:27567 ppid:27566
pid:27568 ppid:27567
pid:27569 ppid:1599
pid:27570 ppid:1599
Which makes no sense to me, so I typed $ps aux to find out what process 1599 is:(with some columns deleted)
USER PID VSZ RSS STAT START COMMAND
linux 1599 63236 6316 Ss 09:03 /lib/systemd/systemd --user
Can anybody help me straighted things up?
The "inconsistency" you observed is because sometimes, the parent process(es) exited before their child process(es) terminated. So, these child processes become "orphans" as their
parent processes are not waiting for them. As a result, they are "re-parented" to the init process.
While traditionally the process id of the "init" process is 1, it's not always true. POSIX leaves it as implementation-defined:
The parent process ID of all of the existing child processes and
zombie processes of the calling process shall be set to the process ID
of an implementation-defined system process. That is, these processes
shall be inherited by a special system process.
Thus you see a particular PID as the parent (1599 in your example), which happens to be "init" process equivalent on your Linux.
The systemd is an init variant used in Debian Linux distributions - which follows a slightly more complicated implementation.
In essense, what you observed is pretty normal. Ideally, you should reap all the processes in order to avoid zombie processes.
I suppose that, sometimes, a race condition happens, and the parent dies before the child. Hence, the child becomes children from init process. In your case, that must be systemd.
Anyway, be advised that running fork(); fork(); will produce 4 processes, which is (probably) not what you intend. Use control structure as you did with the first one to have fine control on the behaviour of your program.
It is because the parent process terminates first.
In Linux there are no ophan processes. They are assigned to the init process.
If you want to control your processes so that child process terminates first, make parent process wait. Using wait() sys_call.
Example:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int pid;
int pid2;
pid = fork();
if(pid < 0){
exit(1);
}
if(pid == 0){ // child process
pid2 = fork()
if (pid2 < 0)
exit(1);
if (pid2 == 0)
{
printf("pid:%dppid:%d\n",getpid(),getppid());
exit(0);
}
wait();
printf("pid:%d ppid:%d\n",getpid(),getppid());
exit(0);
}
else{ // parent process
wait();
printf("parent pid:%d ppid:%d\n",getpid(),getppid());
exit(0);
}
return 0;
}
systemd is an init system used in Linux distributions to bootstrap the
user space and manage all processes subsequently
#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
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main ()
{
int i = 3;
int pid;
while(i > 0) {
pid = fork();
if(pid > 0) {
exit(0);
} else {
i--;
}
}
}
How many process are created on that program??? I am still confused with the fork() system calls, can anybody help me to explain this?
What does fork() do?
fork() is an interesting call. You can think of it as cloning the state of your program into two exact copies -- the only difference between them will be the return value of fork(). The process that did the fork() receives the process id (pid) of the new process, while the new process receives 0.
With that in mind:
How many processes are created?
Each time you fork, you create a new process and exit the parent. You do this three times, therefore -- three processes are created by forking. This doesn't include the one that you started by starting the process, of course. :)
during start of you program, system creates 1 process (+1)
i=3, program creates new process (+1), parent exits, child continue
i=2, program creates new process (+1), parent exits, child continue
i=1, program creates new process (+1), parent exits, child continue
i=0, program exit
so, totally - 4 processes, 3 created by program, 1 by system
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.
May be it look childish for most of you but I am unable to understand this small piece of code.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char** argv) {
int i, pid;
pid = fork();
printf("Forking the pid: %d\n",pid);
for(i =0; i<5; i++)
printf("%d %d\n", i,getpid());
if(pid)
wait(NULL);
return (0);
}
Out put of this program is
Forking the pid: 2223
0 2221
1 2221
2 2221
3 2221
4 2221
Forking the pid: 0
0 2223
1 2223
2 2223
3 2223
4 2223
Press [Enter] to close the terminal ...
In the for loop the printf command is used once. Why "Forking the pid" and after that the pid's are printed twice. How this is working? Can anybody explain me this? Thanks in advance.
Can anybody explain me why we have to use wait here? What I understood from the man pages is wait retuns the control to parent process? Is what I understood is correct?Is it necessary to use wait after forking a process?
Operating system : ubuntu, compiler : gcc, IDE : netbeans
But that' exactly what fork does. You forked the process and everything after the fork is done twice because now you have two processes executing the same printing code. You are basically asking why fork forks. fork forks because is is supposed to fork. That's what it's for.
After fork the parent and the child processes are generally executed in parallel, meaning that the nice sequential output you see in your example is not guaranteed. You might have easily ended up with line-interleaved output from two processes.
wait function in your case is executed from the parent process only. It makes it wait until the child process terminates, and only after that the parent process proceeds to terminate as well. Calling wait in this particular example is not really critical, since the program does nothing after that, it just terminates. But, for example, if you wanted to receive some feedback from the child process into the parent process and do some additional work on that feedback in the parent process, you'd have to use wait to wait for the child process to complete its execution.
The fork() call makes a new process. The rest of the code is then executed from each of the 2 processes. (Man page)
You're printing in both processes. Put your printing loop in an else clause of the if (pid):
pid = fork();
if(pid)
{
printf("Child pid: %d\n",pid);
wait(NULL);
}
else
{
for(i =0; i<5; i++)
printf("%d %d\n", i,getpid());
}
You see, fork returns twice, once in the parent process and once in the child process. It returns 0 in the child and the pid of the created process in the parent.
Because both the parent and child process are outputting their results.
See here: http://en.wikipedia.org/wiki/Fork_(operating_system)#Example_in_C for a good example.
fork creates a new process, and returns in both the old process (the parent) and in the new process (the child).
You can tell which one you are in by looking at the return value from fork. In the parent process it returns the PID of the child process. In the child process it return 0.