Reputation: 15
everyone.
I am taking a course in operating systems and I have the task to programm the following process tree in C with fork. The program must receive 2 arguments the height and the width (of 3 and 2 respectively) and create the tree of this image :
On the image, P.I = Parent Process ,Hijo N= N Child Process, Nieto N = N Grandson and Bisnieto N = N Great Grandson.
The code has to be made from the following template:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i, height, width;
if (argc!= 3) exit(0);
height = atoi(argv[1]); /* height */
width = atoi(argv[2]); /* width */
/* Your code goes here */
printf("I am the process %d and my father is %d\n", getpid(),
getppid());
sleep(1);
return 0;
}
I have made several codes but I cannot find the solution, the closest I have been is the next code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int
main (int argc, char *argv[])
{
int i,x, height, width;
pid_t pid,pid2;
if (argc != 3)
exit (0);
height = atoi (argv[1]); /* height */
width = atoi (argv[2]); /* width */
/* Your code goes here */
for (i = 1; i < height; i++)
{
pid=fork();
if(pid<0){pid2 = fork();}
}
printf ("I am the process %d and my father is %d\n", getpid (), getppid ());
sleep (1);
return 0;
}
But the only thing missing is to create two child processes of the first process (P.I), hijo 2= child 2 of the diagram is not created.
I also tried to create a code that creates a chain of processes one after the other and another code that creates two processes from a parent, but I'm not sure how to join the codes to create this tree. Can someone help me?
This is the code of the chain that I made:
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
int i, height, width;
pid_t pid,pid2;
if (argc!= 3) exit(0);
height = atoi(argv[1]); /* height */
width = atoi(argv[2]);
for (int i=0; i<height; i++)
{
pid = fork();
if (pid == -1) { /* handle error*/ }
else if (pid == 0) {
printf("Soc el process %d y meu pare es %d\n", getpid(),getppid());
}
else { // parent process
wait(NULL);
exit(0);
}
}
printf("Soc el process %d y meu pare es %d\n", getpid(),getppid());
}
The code I made that creates two children of one parent is this one:
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
int i, height, width;
pid_t pid,pid2;
if (argc!= 3) exit(0);
height = atoi(argv[1]); /* height */
width = atoi(argv[2]); /* width */
/* tu codigo aqui */
for(int i=0;i<width;i++) // loop will run n times (n=5)
{
if(fork() == 0)
{
printf("[son] pid %d from [parent] pid %d\n",getpid(),getppid());
exit(0);
}
}
printf("Soc el process %d y meu pare es %d\n", getpid(),getppid());
for(int i=0;i<height;i++) // loop will run n times (n=5)
wait(NULL);
}
I wanted to know if it is a better idea to join the two codes or modify the first one and how to do it: C
Upvotes: 0
Views: 708
Reputation: 12669
The diagram you have shown in your question, depict the behaviour when height is 3
and width is 2
and the behaviour is:
Every process should have 2
(equal to width
) child processes and out of which one child process will exit and one will continue with forking its 2
(equal to width
) child processes... and so on. When the height
is reached, fork 1
child process (and let it exit).
What happen when width will be 3
(or to be more precise, width > 2
?
I am assuming that, in the case, when width is > 2
a process should fork number of child process equal to width
and all child process should exit except one of the child process which will further fork the child processes equal to the given number of width
and this goes on until the height of tree reached. The last parent process will fork width - 1
number of child processes and none of these child processes will further fork any other child process. With this assumption, width
should be >= 1
.
Implementation:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main (int argc, char *argv[]) {
int height, width;
if (argc != 3) {
printf ("Invalid number of arguments, exiting..\n");
exit (0);
}
height = atoi (argv[1]);
width = atoi (argv[2]);
if ((height <= 0) || (width <= 0)) {
printf ("Invalid input.\n"); // error handling can be better
exit (0);
}
printf ("Parent process, my pid = %d, height = %d, width = %d\n", getpid(), height, width);
for (int i = 0; i < height; ++i) {
printf ("\nMy pid : %d, current height of tree : %d, forking..\n", getpid(), i);
pid_t pid;
for (int j = 0; j < width; ++j) {
if ((i + 1 == height) && (j == 0)) {
continue;
}
pid = fork();
if (pid == -1) {
printf ("Fork failed\n");
} else if (pid == 0) {
if (j) {
printf ("My pid = %d, [my parent : %d], I am EXITING..\n", getpid(), getppid());
exit(0);
} else {
printf ("My pid = %d, [my parent : %d], I will fork other child processes..\n", getpid(), getppid());
break;
}
}
}
if (pid) {
break;
} else {
// added sleep for sequenced output, otherwise it's not needed
sleep (1);
}
}
while (wait(NULL) > 0);
printf ("pid %d : I am EXITING\n", getpid());
// added sleep for sequenced output, otherwise it's not needed
sleep (1);
return 0;
}
Output:
# ./a.out 3 2
Parent process, my pid = 3827, height = 3, width = 2
My pid : 3827, current height of tree : 0, forking..
My pid = 3828, [my parent : 3827], I will fork other child processes..
My pid = 3829, [my parent : 3827], I am EXITING..
My pid : 3828, current height of tree : 1, forking..
My pid = 3830, [my parent : 3828], I will fork other child processes..
My pid = 3831, [my parent : 3828], I am EXITING..
My pid : 3830, current height of tree : 2, forking..
My pid = 3832, [my parent : 3830], I am EXITING..
pid 3830 : I am EXITING
pid 3828 : I am EXITING
pid 3827 : I am EXITING
Diagrammatic representation:
--------
| 3827 |
--------
| \
| \
| \
| \
| --------
| | 3829 |
-------- --------
| 3828 |
--------
| \
| \
| \
| \
| --------
| | 3831 |
-------- --------
| 3830 |
--------
\
\
\
\
--------
| 3832 |
--------
Output for height = 3
and width = 4
:
# ./a.out 3 4
Parent process, my pid = 4052, height = 3, width = 4
My pid : 4052, current height of tree : 0, forking..
My pid = 4053, [my parent : 4052], I will fork other child processes..
My pid = 4054, [my parent : 4052], I am EXITING..
My pid = 4055, [my parent : 4052], I am EXITING..
My pid = 4056, [my parent : 4052], I am EXITING..
My pid : 4053, current height of tree : 1, forking..
My pid = 4058, [my parent : 4053], I will fork other child processes..
My pid = 4059, [my parent : 4053], I am EXITING..
My pid = 4060, [my parent : 4053], I am EXITING..
My pid = 4061, [my parent : 4053], I am EXITING..
My pid : 4058, current height of tree : 2, forking..
My pid = 4062, [my parent : 4058], I am EXITING..
My pid = 4063, [my parent : 4058], I am EXITING..
My pid = 4064, [my parent : 4058], I am EXITING..
pid 4058 : I am EXITING
pid 4053 : I am EXITING
pid 4052 : I am EXITING
Upvotes: 1