Reputation: 153
I have this part of my code , runs smoothly but I can't figure out if the second process that is created is a grandchild of the first child , or just a child process . Is this :
if (fork() != 0)
parent(array,N);
else {
child1(array,N);
if(fork() != 0)
child2(array,N);
}
same to that :
if (fork() != 0)
parent(array,N);
else {
child1(array,N);
}
if (fork() == 0)
child2(array,N);
cause I'm getting the same results . The programm is having an array and parent computes the max of the fir 1/3 of the array , the 1st child the second 1/3 and the 2nd child the third . Parent gets results from pipes from the children and prints them . Runs the same for the 2 versions I exhibit above .
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
int pfd1[2],pfd2[2]; // pfd[1] gia to prwto paidi , pfd[2] gia to deutero paidi
void parent(int array[],int N) {
int i;
int max_p;
int child1_max,child2_max; //auto pou 8a steilei
max_p=array[0]; // <============================================================================
close(pfd1[1]); //no writing by the parent
close(pfd2[1]); //no writing by the parent
for(i=0;i<N/3;i++) {
if(array[i]>max_p) {
max_p=array[i];
}
}
waitpid(-1, NULL, 0); /* Wait my child process */
read(pfd1[0],&child1_max,sizeof(int)); //get 1st child's max_c
close(pfd1[0]);
read(pfd2[0],&child2_max,sizeof(int)); //get 1st child's max_c
close(pfd2[0]);
printf("1st child_max is %d\n",child1_max);
printf("2nd child_max is %d\n",child2_max);
printf("parents max is %d\n",max_p);
/*if(max_p>child_max) {
printf("max is %d (was in parent)\n",max_p);
printf("max of child is %d\n",child_max);
}else {
printf("max is %d (was in child)\n",child_max);
printf("max of parent is %d\n",max_p);
}*/
}
void child1(int array[],int N) {
int i;
int max_c=array[N/2]; // <============================================================================
close(pfd1[0]); // No reading by child
for(i=N/3;i<(2*N)/3;i++) {
if(array[i]>max_c) {
max_c=array[i];
}
}
write(pfd1[1],&max_c,sizeof(int));
close(pfd1[1]);
}
void child2(int array[],int N) {
int i;
int max_c=array[(2*N)/3]; // <============================================================================
close(pfd2[0]); // No reading by child
for(i=(2*N)/3;i<N;i++) {
if(array[i]>max_c) {
max_c=array[i];
}
}
write(pfd2[1],&max_c,sizeof(int));
close(pfd2[1]);
}
int main(void) {
int array[]={111,1222,10,392,3211,3,2,50,8};
int N=sizeof(array)/sizeof(int);
//printf("\n %d \n",N);
if (pipe(pfd1) < 0)
{
perror("pipe()");
exit(1);
}
if (pipe(pfd2) < 0)
{
perror("pipe()");
exit(1);
}
if (fork() != 0)
parent(array,N);
else {
child1(array,N);
//if(fork() != 0)
// child2(array,N);
}
if (fork() == 0)
child2(array,N);
return 0;
}
Upvotes: 0
Views: 1738
Reputation: 624
First off, these are not the same. In the second piece of code both the parent and the child created from the first if (fork() != 0)
will call the second if (fork() == 0)
(creating two more child processes with one being a grandchild).
In the first piece of code, only the child created by if (fork() != 0)
will call the second if(fork() != 0)
. In both examples there is a grandchild process.
Also, in the first piece of code, you call child2(array,N)
as the parent (well, as the first child). By doing this you end up forking for no reason. You should do if (fork() == 0)
if you want the child to call child2(array,N)
(and thus be the true grandchild). Right now, the grandchild process just exits.
Here is a tree to show the forks.
The tree for the first piece of code. Note, evert split on the tree represents a fork call. When we go up we are the child process and when we go down we are the parent of the fork. I added delays in the tree to show the waits.
The tree for the second piece of code:
The reason that you are getting the same results is because the second child2
that gets called by the parent process happens after you print the results.
Also, in parent
you only wait for the first child but you use results from the second child. You should also add some wait logic to child1
.
I would suggest you use the following
if (fork() != 0)
parent(array,N);
else {
child1(array,N);
if(fork() == 0)
child2(array,N);
}
Here, child2
is called as the grandchild process.
Upvotes: 2
Reputation: 780974
In the first example we have the following processes:
Parent
parent()
Child
child1()
child2()
Grandchild
Doesn't so anything
because the second fork()
is being done in the child process. It then calls child2()
when the result is non-zero, which means it's the same process that called fork()
. Since there's no else
block to the second if
, the grandchild doesn't run any code (actually, it will run the code that follows everything you posted).
The second example has the following:
Parent
parent()
Child 1
child1()
Child 2
child2()
In this case, the second fork()
is executed in the original process.
Also, if child1()
doesn't exit the process, the Child 1 process will continue executing after the first if/else
is done, so it will also execute the second fork()
. You'll then get the following:
Parent
parent()
Child 1
child1()
Grandchild
child2()
Child 2
child2()
Upvotes: 2