Pass the value from child to parent process

30,763

Solution 1

You can do this with a very easy technique, which is shared memory. I will give a complete example of how it works.

First, let's assume I want to write a program to print the first nterms in Fibonacci series (and I know it is not that logical to do so, but it is an easy example so everyone can understand it).

  1. I have a parent which reads an integer value representing the first n terms
  2. Then the parent process will create a child and pass n to it
  3. Then the child should calculate the first n terms and return them back to the parent.

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/stat.h>

void printFibo(int n, int *fibo)
{
    int i;
    for(i=0; i<=n; i++)
        printf("%d -> %d\n" ,i, fibo[i]);
}

void computeFibo(int n, int *fibo) 
{
    int i;
    fibo[0] = 0;
    fibo[1] = 1;

    for (i=2; i<=n; i++) 
        fibo[i] = fibo[i-1] + fibo[i-2];
}

int main(int argc, char *argv[])
{
    pid_t childPID;
    int status;
    int shm_fd;
    int* shared_memory;
    int msize; // the size (in bytes) of the shared memory segment 
    const char *name = "FIBONACCI_SERIES";
    int n;

    if (argc!=2) 
    {
        fprintf(stderr, "usage: %s <Fibonacci number to be generated>\n", argv[0]);
        return -1;
    }

    n = atoi(argv[1]);
    if (n < 0) 
    {
        fprintf(stderr, "Illegal fibonacci number: %s\n", argv[1]);
        return -2;
    }

    // calculating the array size based on the number of terms being passed from child to parent
    msize = (n+2)*sizeof(int); 

    // open the memory
    shm_fd = shm_open (name, O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG);
    if (shm_fd < 0) 
    {
        fprintf(stderr,"Error in shm_open()");
        return -3;
    }

    printf("Created shared memory object %s\n", name);

    // attach the shared memory segment
    ftruncate(shm_fd, msize);
    printf("shmat returned\n");

    // allocating the shared memory
    shared_memory = (int *) mmap(NULL, msize, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
    if (shared_memory == NULL) 
    {
        fprintf(stderr,"Error in mmap()");
        return -3;
    }

    printf("Shared memory segment allocated correctly (%d bytes).\n", msize);

    shared_memory[0] = n;

    childPID=fork();
    if ( childPID == -1 ) 
    {
        fprintf(stderr, "Cannot proceed. fork() error");
        return -4;
    }
    if (childPID  == 0) 
    {
        // then we're the child process
        computeFibo(shared_memory[0],shared_memory+1);
        exit(0);
    }
    else
    {
        // parent will wait until the child finished
        wait(&status);

        // print the final results in the 
        printFibo(shared_memory[0], shared_memory+1);

        // now detach the shared memory segment
        shm_unlink(name);
    }
    return 0;
}

Solution 2

If you want to do it without using any way of communication i.e pipes, shared memory then you will have to use exit() system call. The exit system call return a signal that is then caught by wait() system call in parent process. Here I am giving you a code in which I am sending a value from child to parent. One last thing you have to divide the signal caught by wait by 255 to get the exact value. `

    #include<unistd.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<sys/wait.h>
    int main(int argc,char *argv[])
    {
       pid_t pid=fork();
       if(pid==0)
       {//child
            int sum=5+7;
            exit(sum);//sending exiting status or any value to parent
       }
       else
       {//parent
            int childval=-1;
            wait(&childval);//catching signal sent by exit of(child) 
            printf("%d",childval/255);//changing signal to exact value  
       }    
        return 0;
    }

`

Solution 3

fork makes a copy of the process, so once you call fork child processes have their own copy of the variables t1, t2 and t3 which you expect to read from the parent.

So once you exit children, the children die along with the calculated values which are local to them.

If you want to read values from children, you have to use pipes or shared memory.

Solution 4

You have to create pipe in the parent process, than after fork you must to close input file descriptor in the child process and close output file descriptor in the parent process.

There is example from the pipe(2) man page.

   #include <sys/wait.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <unistd.h>
   #include <string.h>

   int
   main(int argc, char *argv[])
   {
       int pipefd[2];
       pid_t cpid;
       char buf;

       if (argc != 2) {
        fprintf(stderr, "Usage: %s <string>\n", argv[0]);
        exit(EXIT_FAILURE);
       }

       if (pipe(pipefd) == -1) {
           perror("pipe");
           exit(EXIT_FAILURE);
       }

       cpid = fork();
       if (cpid == -1) {
           perror("fork");
           exit(EXIT_FAILURE);
       }

       if (cpid == 0) {    /* Child reads from pipe */
           close(pipefd[1]);          /* Close unused write end */

           while (read(pipefd[0], &buf, 1) > 0)
               write(STDOUT_FILENO, &buf, 1);

           write(STDOUT_FILENO, "\n", 1);
           close(pipefd[0]);
           _exit(EXIT_SUCCESS);

       } else {            /* Parent writes argv[1] to pipe */
           close(pipefd[0]);          /* Close unused read end */
           write(pipefd[1], argv[1], strlen(argv[1]));
           close(pipefd[1]);          /* Reader will see EOF */
           wait(NULL);                /* Wait for child */
           exit(EXIT_SUCCESS);
       }
   }
Share:
30,763
KobeBryant
Author by

KobeBryant

Updated on July 14, 2022

Comments

  • KobeBryant
    KobeBryant almost 2 years

    I have this code that is supposed to create three child process' and each will perform a small mathematical operation. Then, the parent is supposed to use the results from all the child process' and get a final answer but I can't find a way to actually read the result from the child in the parent. Is there a way to do this?

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    int main(void)
    {
       int pid1, pid2, pid3, status;
       int a=1, b=2, c=5, d=4, e=6, f=3, g;
       int t1, t2, t3;
    
       printf("Hello World!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
       printf("Here I am  before use of forking\n");
       printf("I am the PARENT process and pid is : %d\n",getpid());
    
       pid1 = fork( );
       if (pid1 == 0)
       {      
        printf("\n\nHere I am just after child forking1\n");
        printf("I am the Child process and pid1 is :%d\n",getpid());      
        printf("My parent's pid is :%d\n",getppid());   
        t1 = a+b;
        printf("The answer for t1 is: %d\n", t1);       
        exit(0);
       }
       else
       {
        wait(&status);
            printf("\nHere I am just after parent forking1\n");
            printf("I am the Parent process and pid is: %d\n",getpid());
       }
    
       pid2 = fork( );
       if (pid2 == 0)
       {      
        printf("\n\nHere I am just after child forking2\n");
        printf("I am the Child process and pid2 is :%d\n",getpid());      
        printf("My parent's pid is :%d\n",getppid());   
        t2 = c+d;
        printf("The answer for t2 is: %d\n", t2);   
        exit(0);    
       }
       else
       {
        wait(&status);
            printf("\nHere I am just after parent forking2\n");
            printf("I am the Parent process and pid is: %d\n",getpid());
       }
    
       pid3 = fork( );
       if (pid3 == 0)
       {      
        printf("\n\nHere I am just after child forking3\n");
        printf("I am the Child process and pid3 is :%d\n",getpid());      
        printf("My parent's pid is :%d\n",getppid());   
        t3 = e/f;   
        printf("The answer for t3 is: %d\n", t3);   
        exit(0);
       }
       else
       {
        wait(&status);
            printf("\nHere I am just after parent forkingALL\n");
            printf("I am the Parent process and pid is: %d\n",getpid());
       }
    
    
       printf("\n\nThe final answer for t1 is: %d\n", t1);
       printf("The final answer for t2 is: %d\n", t2);
       printf("The final answer for t3 is: %d\n", t3);
    
    
       g = t1*t2-t3;
       printf("The final answer for g is: %d\n", g);
    }