LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Splitting a parent process into 2 child and then merging result. (https://www.linuxquestions.org/questions/programming-9/splitting-a-parent-process-into-2-child-and-then-merging-result-832312/)

chandan_maheshwari16 09-15-2010 08:38 AM

Splitting a parent process into 2 child and then merging result.
 
Hi All,
I am new to this group, also havent worked much on linux.
What i am trying to do is i want to add numbers from 1 to 100.

but that too using multiprocessing. So i made a c programme and using fork() command made two child processes. Now in one child process i am adding from 1 to 50. and in another i am adding 51 to 100. and then in the parent process adding the two results to get the final one.

Now the result from the two function i am getting correctly. But after the wait() call the value returned is lost :
See the programme below for reference


# include<stdio.h>
# include<unistd.h>
# include<sys/wait.h>
# include<stdlib.h>
int *sum1to50()
{
int i;
int sum1=0;
printf("\nWill add 1 to 50\n");
for (i=1;i<51;i++)
sum1+=i;
printf("\nfrom function 1%d",sum1);
//sum1=sum+sum1;
return &sum1;
}


int *sum51to100()
{
int i,sum2=0;
printf("\nWill add 51 to 100\n");
for (i=51;i<101;i++)
sum2+=i;
//sum2=sum+sum2;
return &sum2;
}


int main()
{
pid_t pid1,pid2,wpid1,wpid2;
int status1,status2;//,sum1,sum2,sum;
static int sum1=0;
static int sum2=0;
static int* sum=0;
system("date");
//int sum3;
//int sum;
//creating the first child program to add 1 to 50
pid1 = fork();
if(pid1==-1)
perror("\nError creating process\n");
else if(pid1==0)
{
printf("\nInside Process 1\n");
sleep(15);
sum1=*sum1to50();
printf("\nFunction 1 returned sum 1 to 50 %d\n",sum1);
*sum=sum+sum1;
//printf("\nFrom loop 1 %d\n",*sum);
printf("\nExiting process 1\n");
exit(1);
}


//continue with the main program

//creating the second child program to add 51 to 100
pid2 = fork();
if(pid2==-1)
perror("\nError creating process\n");
else if(pid2==0)
{
sleep(5);
printf("\nInside process 2\n");
sum2=*sum51to100();
printf("\nFunction 2 returned sum 51 to 100 %d\n",sum2);
*sum=sum+sum2;
printf("\n from loop 2 %d\n",*sum);
printf("\nExiting Process 2\n");
exit(1);
}
wpid1=wait(&status1);
if(wpid1 == (pid_t)-1)
perror("\nerror\n");

wpid2=wait(&status2);
if(wpid2 == (pid_t)-1)
perror("\nerror\n");

printf("\n All the child processes have finished there task\n");

printf("\nThis program will give addition from 1 to 100");

//sum=sum1+sum2;
printf("%d\n",*sum);
system("date");
//printf("\nsum1 %d\n",*sum1);
//sum=sum1+sum2;
printf("%d\n",*sum);
system("date");

return 0;

}


I have tried every possible way upto my knowledge but no fruitful result.(used pointers.....

akuehn 09-15-2010 09:53 AM

Hey!

Well, fork is probably not what you want, as it creates a new process with its own memory etc. In fact, you create a copy of the first process.

If you really want to do something in parallel, use pthreads for example. Here is a rough plot on that idea.

void *sum1fkt(void *data)
{
int *sum = (int*) data;

*sum = 2+3;
...
return 0
;
}

void *sum2fkt(void *data)
{
...
return 0;
}

int main(int argc, char **argv)
{
int sum1, sum2;
pthread_t id1, id2;

pthread_create(&id1, NULL, sum1fkt, &sum1);
pthread_create(&id2, NULL, sum2fkt, &sum2);

pthread_join(...);
return (sum1 + sum2);
}

ForzaItalia2006 09-15-2010 05:37 PM

Hey,

as described in the previous post, you can't use fork(2) the way you did. You do basically have at least two choices: (a) use a multi-threading approach as already described or (b) to use a multi-process approach. While the multi-threading approach is simpler from the communication aspect as the virtual memory is shared by all threads, the multi-process approach allows a greater flexibility and scalability. The tricky part of the multi-process approach is the communication aspect between between the parent and all the children who might possibly distributed to different hosts. Just some keywords which might help you to get some more details:

* shared memory
* message queues
* sockets
* MPI (message passing-interface)
* ...

Hope that helps at least a bit,
Andi

chandan_maheshwari16 09-15-2010 11:04 PM

It helped....some more
 
hi akuehn,
thanks for the reply... but i do know that using thread we can do so... but i was jus trying to do the same by creating more processess. Cant we do like this?

Also one more thing when i take a addition inside the if loop like (given below in bold) and then print the statement , then it doesnt print that line (the compiler doesnt go there....confused why)

else if(pid1==0)
{
printf("\nInside Process 1\n");
sleep(15);
sum1=*sum1to50();
printf("\nFunction 1 returned sum 1 to 50 %d\n",sum1);
*sum=sum+sum1;
printf("\nFrom loop 1 %d\n",*sum);
printf("\nExiting process 1\n");
exit(1);
}


is that a drawback of creating processes that we cannot return a value from them.. Then where exactly v can use them.

chandan_maheshwari16 09-15-2010 11:13 PM

Quote:

Originally Posted by ForzaItalia2006 (Post 4098738)
Hey,

as described in the previous post, you can't use fork(2) the way you did. You do basically have at least two choices: (a) use a multi-threading approach as already described or (b) to use a multi-process approach. While the multi-threading approach is simpler from the communication aspect as the virtual memory is shared by all threads, the multi-process approach allows a greater flexibility and scalability. The tricky part of the multi-process approach is the communication aspect between between the parent and all the children who might possibly distributed to different hosts. Just some keywords which might help you to get some more details:

* shared memory
* message queues
* sockets
* MPI (message passing-interface)
* ...

Hope that helps at least a bit,
Andi

hi...
Thanks
hello that is what i am saying how to use multi processing approach, is the one that i have used is not the same approach

chandan_maheshwari16 09-15-2010 11:37 PM

Using MPI
 
Quote:

Originally Posted by ForzaItalia2006 (Post 4098738)
Hey,

as described in the previous post, you can't use fork(2) the way you did. You do basically have at least two choices: (a) use a multi-threading approach as already described or (b) to use a multi-process approach. While the multi-threading approach is simpler from the communication aspect as the virtual memory is shared by all threads, the multi-process approach allows a greater flexibility and scalability. The tricky part of the multi-process approach is the communication aspect between between the parent and all the children who might possibly distributed to different hosts. Just some keywords which might help you to get some more details:

* shared memory
* message queues
* sockets
* MPI (message passing-interface)
* ...

Hope that helps at least a bit,
Andi



hello i have used MPI also,
here also confused where to add the final result means in which process(i have used two nodes and 1 task /node)



# include "mpi.h"
# include <stdio.h>

int main(argc,argv)

int argc;
char *argv[];
{
int numtasks,rank=-1, rc;
int sum1=0,sum2=0,sum=0,i;
rc= MPI_Init(&argc,&argv);
if(rc != MPI_SUCCESS)
{
printf("\nerror starting MPI program \n");
MPI_Abort(MPI_COMM_WORLD,rc);
}

MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if(rank==0)
{
printf("no. of tasks=%d My rank=%d\n",numtasks,rank);
for(i=0;i<11;i++)
{
sum1+=i;
}
sum=sum+sum1;
printf("hello exiting %d process\n",rank);
printf("the sum from1 to 10 is %d\n",sum1);
}

if(rank==1)
{
printf("no. of tasks=%d My rank=%d\n",numtasks,rank);
for(i=11;i<21;i++)
{
sum2+=i;
}
sum=sum+sum2;
printf("the sum from11 to 21 is %d\n",sum2);
printf("hello exiting %d process\n",rank);
}
printf("the total sum is%d \n",sum);
MPI_Finalize();

}
the output its giving is :....(on AIX)

no. of tasks=2 My rank=0
hello exiting 0 process
the sum from1 to 10 is 55
no. of tasks=2 My rank=1
the sum from11 to 21 is 155
hello exiting 1 process
the total sum is55
the total sum is155

akuehn 09-16-2010 03:02 AM

Good Morning!

Keeping the posting from "ForzaItalia2006" in mind, all that holds generally!

You try to create parallel instances of functions (sum1, sum2,...) but you create processes by using fork(). That is the underlying problem.

Linux can run only processes in parallel. Thus, in all cases we end up in what "ForzaItalia2006" posted. It is the communication and synchronisation of your worker functions. MPI simplifies some aspects but is actually oversized for your intention.

Coming back to your fork() idea and a communication solution. You can create a pipe() to communicate between child and parent. An example can be found here: http://www.cs.cf.ac.uk/Dave/C/node23.html

Have a nice day
akuehn


All times are GMT -5. The time now is 05:25 PM.