Search code examples
cfork

how to return value from children process to parent?


I know there is some question about this already, but I don't understand what I'm doing wrong here. I'm reading numbers from file, and storing them into array. Now I want to create process that the parent is reading 10 numbers, then the children read the other numbers, add them together and send to the parent process, but for some reason the return value I'm getting is wrong. what I'm missing here? I added image to demonstrate example

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>

int my_read(char *arg1);

int main(int argc, char *argv[])
{
  my_read("numbers.txt");
}

int my_read(char *arg1)
{
  int status;
  int avg = 0;
  int p, i;
  int arr[26];

  FILE *file = fopen(arg1, "r");

  if (NULL == file)
  {
    printf("file can't be opened \n");
  }

  fscanf(file, "%d", &i);
  while (!feof(file))
  {
    arr[p] = i;
    p++;
    fscanf(file, "%d", &i);
  }
  arr[25] = i;

  // fork
  printf("I am the parent: %d\n", (int)getpid());

  pid_t pid = fork();

  if (pid < 0)
  { /* error occurred */
    perror("Fork failed");
  }
  if (pid == 0)
  { /* child process */
    printf("I am the child with pid %d\n", (int)getpid());
    for (i = 10; i < 26; i++)
    {
      printf("%d\n", arr[i]);
      avg += arr[i];
    }
    exit(avg);//send to parent
    
  }

  /* parent process */

  for (i = 0; i < 10; i++)
  {
    printf("%d\n", arr[i]);
  }

  wait(&status);
  printf("I am the parent: %d\n", (int)getpid());
  printf("%d\n", status);

  fclose(file);
  return (0);
}

Solution

  • This code deals with most of the problems outlined in my comments. One area it addresses that wasn't highlighted in the comments is the fragility of the original code — it assumes that there will be exactly 26 numbers in the file. This code ensures that only 26 numbers are read.

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    #include <unistd.h>
    
    int my_read(char *arg1);
    
    int main(void)
    {
      my_read("numbers.txt");
      return 0;
    }
    
    int my_read(char *arg1)
    {
      int status;
      int avg = 0;
      int p, i;
      int arr[26];
    
      FILE *file = fopen(arg1, "r");
    
      if (NULL == file)
      {
        fprintf(stderr, "file '%s' can't be opened for reading\n", arg1);
        exit(EXIT_FAILURE);
      }
    
      p = 0;
      while (fscanf(file, "%d", &i) == 1 && p < 26)
        arr[p++] = i;
    
      fclose(file);
    
      /* p contains the number of values */
    
      // fork
      printf("I am the parent: %d\n", (int)getpid());
    
      pid_t pid = fork();
    
      if (pid < 0)
      { /* error occurred */
        perror("Fork failed");
      }
      if (pid == 0)
      { /* child process */
        printf("I am the child with pid %d\n", (int)getpid());
        for (i = 10; i < p; i++)
        {
          printf("%d\n", arr[i]);
          avg += arr[i];
        }
        printf("Sum of values: %d\n", avg);
        avg /= (26 - 10);
        printf("Avg of values: %d (0x%.2X)\n", avg, avg);
        exit(avg);//send to parent
      }
    
      /* parent process */
    
      for (i = 0; i < 10; i++)
      {
        printf("%d\n", arr[i]);
      }
    
      wait(&status);
      printf("I am the parent: %d\n", (int)getpid());
      printf("Raw: 0x%.4X\n", status);
      printf("Value: %d\n", WEXITSTATUS(status));
    
      return (0);
    }
    

    Given the input file (with 4 extra primes):

    1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
    101 103 107 109
    

    it still works correctly — and produces output such as:

    I am the parent: 18797
    1
    2
    3
    5
    7
    11
    13
    17
    19
    23
    I am the child with pid 18798
    29
    31
    37
    41
    43
    47
    53
    59
    61
    67
    71
    73
    79
    83
    89
    97
    Sum of values: 960
    Avg of values: 60 (0x3C)
    I am the parent: 18797
    Raw: 0x3C00
    Value: 60
    

    Note that it is preferred not to include screenshots of plain text; showing it as text in the question is fine.