Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass the value from child to parent process

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);
}
like image 367
KobeBryant Avatar asked Sep 19 '12 17:09

KobeBryant


Video Answer


2 Answers

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;
}
like image 114
Ahmed Hamdy Avatar answered Oct 26 '22 23:10

Ahmed Hamdy


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;
    }

`

like image 37
Muhammad Raghib Avatar answered Oct 26 '22 23:10

Muhammad Raghib