将值从子进程传递给父进程

时间:2012-09-19 17:19:59

标签: c linux fork parent-child

我有这个应该创建三个子进程的代码',每个代码都执行一个小的数学运算。然后,父母应该使用来自所有子进程的结果'并获得最终答案,但我找不到实际读取父进程中子进程的结果的方法。有没有办法做到这一点?

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

4 个答案:

答案 0 :(得分:4)

您可以使用非常简单的技术执行此操作,即共享内存。我将举一个完整的例子说明它是如何工作的。

首先,让我们假设我想编写一个程序来打印Fibonacci系列中的第一个n(我知道这样做是不合逻辑的,但它是一个简单的例子,所以每个人都可以理解它。

  1. 我有一个父项,它读取一个表示第一个n
  2. 的整数值
  3. 然后父进程将创建一个子进程并将n传递给它
  4. 然后孩子应该计算前n个术语并将它们还给父母。

  5. #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;
    }
    

答案 1 :(得分:3)

如果你想在不使用任何通信方式的情况下这样做,即管道,共享内存,那么你将不得不使用exit()系统调用。 exit系统调用返回一个信号,然后由父进程中的wait()系统调用捕获。在这里,我给你一个代码,我在其中发送一个从child到parent的值。最后一件事你必须将等待的信号除以255得到确切的值。     `

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

`

答案 2 :(得分:2)

fork复制了这个过程,所以一旦你调用fork子进程有自己的变量t1,t2和t3,你希望从父进程中读取它们。

因此,一旦你exit孩子,孩子就会死于他们当地的计算值。

如果您想阅读儿童的值,您必须使用pipes或共享内存。

答案 3 :(得分:1)

您必须在父进程中创建管道,而不是在fork之后,您必须关闭子进程中的输入文件描述符并关闭父进程中的输出文件描述符。

管道(2)手册页中有例子。

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