Pass the value from child to parent process

早过忘川 提交于 2019-12-03 08:09:42

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

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

`

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.

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);
       }
   }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!