Home > Blockchain >  Pass every time each row of array to child
Pass every time each row of array to child

Time:02-02

I am reading from the user the size of an arr. I create the arr[row][col] and fill it with random integers. Then i want to send each row from the parent process to the child so i create a new arr2 to store every time the current row in it. I read the arr2 to child process and calculating the sum of the row. At the end i want to send the sum to parent process and print it. I do this in a for(i=0;i<row;i ). The problem is that the child process only takes the first row every time.

#include <sys/types.h>
#include<stdio.h>
#include <unistd.h>
#include<time.h>
#include<stdlib.h>

int main(){

int gram, steiles;

printf("Dwse mou tis grammes tou pinaka\n");
scanf("%d", &gram);
printf("Dwse mou tis steiles tou pinaka\n");
scanf("%d", &steiles);

int arr[gram][steiles];
int arr2[gram];

srand(time(NULL));

for (int i = 0; i < gram; i  ) {
  for (int j = 0; j < steiles; j  ) {
    arr[i][j] = rand() % 20   1;
  }
}

for (int i = 0; i < gram; i  ) {
  for (int j = 0; j < steiles; j  ) {
    printf("%d", arr[i][j]);
    printf("\t");
  }
  printf("\n");
}
pid_t pid;
int fd[2], fd1[2], sum=0;

if (pipe(fd) == -1) {
  return 2;
}
if (pipe(fd1) == -1) {
  return 3;
}

    for (int i = 0; i < gram; i  ) {
      pid = fork();
    
      if (pid<0) {
        return 1;
      }
    
      if (pid>0){   
        for (int j = 0; j < steiles; j  ) {
          arr2[j]=arr[i][j];
        }
    
        close(fd[0]);
        write(fd[1], arr2, sizeof(int)*steiles);
        close(fd[1]);
    
        close(fd1[1]);
        read(fd1[0], &sum, sizeof(int));
        close(fd1[0]);
        printf("the sum of the row is: %d", sum);
    
    
      }else{ 
        wait(NULL);
        close(fd[1]);
        read(fd[0], arr2, sizeof(int)* steiles);
        close(fd[0]);
        for (int k = 0; k < steiles; k  ) {
          // printf("%d\t", arr2[k]);
          sum =arr2[k];
        }
        close(fd1[0]);
        write(fd1[1], &sum, sizeof(int));
        close(fd1[1]);
      }
}
}

CodePudding user response:

I've outlined many of the problems in the comments above, including:

  • You don't error check your I/O calls but should.
  • The parent process closes the pipes for the first child; the second and subsequent children don't stand a chance, poor things. They've been deprived of all communication with the parent, and you know how much children benefit from talking with their parents.
  • Create the pipes inside the loop, not outside. Note that error checking the I/O calls would have told you about this problem.
  • Don't forget to end messages with newlines.
  • Also, make sure your child processes exit after they've done their stuff. As it stands, the first child reads its data, and then goes back around the loop to run a new child (as well as the parent running a new child).

Here's some code which still skips on the I/O error checking but works correctly:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

static void dump_vector(const char *tag, size_t size, const int *data);

int main(void)
{
    int gram, steiles;

    printf("Dwse mou tis grammes tou pinaka\n");
    scanf("%d", &gram);
    printf("Dwse mou tis steiles tou pinaka\n");
    scanf("%d", &steiles);

    int arr[gram][steiles];
    int arr2[gram];

    srand(time(NULL));

    for (int i = 0; i < gram; i  )
    {
        for (int j = 0; j < steiles; j  )
        {
            arr[i][j] = rand() % 20   1;
        }
    }

    for (int i = 0; i < gram; i  )
    {
        for (int j = 0; j < steiles; j  )
        {
            printf("%d", arr[i][j]);
            printf("\t");
        }
        printf("\n");
    }

    for (int i = 0; i < gram; i  )
    {
        pid_t pid;
        int fd1[2], fd2[2];

        if (pipe(fd1) == -1)
        {
            return 2;
        }
        if (pipe(fd2) == -1)
        {
            return 3;
        }
        pid = fork();

        if (pid < 0)
        {
            return 1;
        }

        if (pid > 0)
        {
            for (int j = 0; j < steiles; j  )
            {
                arr2[j] = arr[i][j];
            }

            dump_vector("arr2 - parent", steiles, arr2);

            close(fd1[0]);
            write(fd1[1], arr2, sizeof(int) * steiles);
            close(fd1[1]);

            int sum = 0;
            close(fd2[1]);
            read(fd2[0], &sum, sizeof(int));
            close(fd2[0]);
            printf("the sum of the row is: %d\n", sum);
        }
        else
        {
            close(fd1[1]);
            read(fd1[0], arr2, sizeof(int) * steiles);
            close(fd1[0]);
            dump_vector("arr2 - child", steiles, arr2);
            int sum = 0;
            for (int k = 0; k < steiles; k  )
            {
                // printf("%d\t", arr2[k]);
                sum  = arr2[k];
            }
            printf("Child %d (%d): sum = %d\n", i, getpid(), sum);
            close(fd2[0]);
            write(fd2[1], &sum, sizeof(int));
            close(fd2[1]);
            exit(0);
        }
    }
    return 0;
}

static void dump_vector(const char *tag, size_t size, const int *data)
{
    int length = printf("%s (%zu):", tag, size);
    for (size_t i = 0; i < size; i  )
    {
        length  = printf(" -", data[i]);
        if (length > 60)
        {
            length = 0;
            putchar('\n');
        }
    }
    if (length > 0)
        putchar('\n');
}

I find that functions like dump_vector() are very helpful; I write them for many data structures. Sometimes I accept a FILE *fp argument too, but the tag is crucial. For arrays, size and data are necessary; for single structures, just the structure, of course.

Example output

Dwse mou tis grammes tou pinaka
4
Dwse mou tis steiles tou pinaka
10
12  12  4   3   8   12  6   4   2   10  
10  13  14  13  13  1   7   12  4   8   
7   12  19  12  14  18  20  13  8   8   
5   14  7   11  19  16  4   12  14  18  
arr2 - parent (10): 12 12  4  3  8 12  6  4  2 10
arr2 - child (10): 12 12  4  3  8 12  6  4  2 10
Child 0 (15771): sum = 73
the sum of the row is: 73
arr2 - parent (10): 10 13 14 13 13  1  7 12  4  8
arr2 - child (10): 10 13 14 13 13  1  7 12  4  8
Child 1 (15772): sum = 95
the sum of the row is: 95
arr2 - parent (10):  7 12 19 12 14 18 20 13  8  8
arr2 - child (10):  7 12 19 12 14 18 20 13  8  8
Child 2 (15773): sum = 131
the sum of the row is: 131
arr2 - parent (10):  5 14  7 11 19 16  4 12 14 18
arr2 - child (10):  5 14  7 11 19 16  4 12 14 18
Child 3 (15774): sum = 120
the sum of the row is: 120
  •  Tags:  
  • Related