Greetings everyone, I need a bit of help in solving the following problem:
I'm given an array of numbers and I have to compute the sum of the array elements using n processes, and the inter process communication has to be done with pipes(one pipe, to be exact).
I managed to solve the problem by waiting for a random child to finish, reading the sum sent by the child through the pipe, and so on for the following children, and incrementing the final sum.
Now I have to solve it by reading the partial sums in one fell swoop, after all the children have finished, and I'm not sure as to how to save the entire information sent by the kids. I tried to use a for statement, but it failed, since all the information would be passed in one single element of the array, and offering only the address of the first element in the array failed as well.
Any input would be much appreciated.
Here is the code that's bugging me:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
void main () {
int size, fd [2];
printf ("enter the size of the number array: ");
scanf ("%d", &size);
int i, arr ;
for(i=0; i < size; i++)
arr = i + 1;
int nr_proc;
printf ("enter the number of processes that you want to use: ");
scanf ("%d", &nr_proc);
pid_t pid [nr_proc];
for (i = 0; i < nr_proc; i++) {
pipe (fd);
pid = fork ();
if (pid < 0)
printf ("error in fork.\n");
if (pid == 0) {
close (fd [0]);
int j = 0, sum = 0;
for (j = i * size/nr_proc; j < (i+1) * size/nr_proc; j++) {
sum += arr[j];
}
printf ("test %d\n", sum);
write(fd [1], &sum, sizeof (int));
exit (1);
}
}
close (fd [1]);
for (i = 0; i < nr_proc; i++)
wait ();
int aux[nr_proc], test = 0;
read (fd [0], aux, sizeof(aux)); // this is where i need help
printf ("test aux %d\n", aux [1]);
int sum = 0;
for (i = 0; i < nr_proc; i++)
sum += aux ;
printf ("result = %d\n", sum);
}
Sorry about that, I'm not a native english speaker. I'll try to give an example:
suppose we have this array:
arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
I want to compute the sum of it's elements using 2 child processes, to do so we'll split the array in two equal(or almost equal, if the number of elements is an odd number), and the first child will compute:
(1+2+3+4+5 = 15)
while the second will do:
(6+7+8+9+10 = 40).
Now, each child will send their computed sum to the parent through the pipe fd(2). The problem I'm having is that I don't know how to save both sums at the same time, that is, if I try to read the sums after all kids have finished, for example
int buffer[2];
read (fd (0), buffer, sizeof (buffer));
will first assign 15 to buffer [0], and then he'll assign 40 to buffer [0] , and i want it to assign 15 to buffer [0] and 40 to buffer [1]
Corona, that's my exact problem, I'm not allowed to make multiple reads this time, I already solved it that way by waiting for a child, reading the pipe, repeat . I have to figure out a mechanism that allows me to read everything in the pipe at once, and store it, been googling for pipe I/O for a few hours now to no avail :wall:.
I followed your advice on checking the returned value of read () and write (), read returns 4 bytes, which is the same as what write() returns, I believe that means I only get the chance to read the input from the child that finishes last, as he overwrites the pipe ?
At this point I only see 2 solutions for the problem, the one I already solved, and having a pipe for every child like shamrock suggested(an array of pipes maybe ?), will try the sham's proposal.
But if you are allowed to call read only once in the parent then it wont work as my solution requires 2 reads. Going over your posted code it looks like you start with one parent then fork creating a child which then forks itself creating another child...so you end up having a parent a child and a grandchild. Is that how you are supposed to approach it as that simplifies things and makes it completely doable with a single read in the parent.
you should give this a fixed number not a variable. sizeof() is set at compile-time and knows nothing about variable-size arrays. I think sizeof() is only giving you 4.