【问题标题】:Receiving a return value from a child process into a parent process?从子进程接收返回值到父进程?
【发布时间】:2018-03-13 20:22:31
【问题描述】:

我在这里阅读了一些主题以获取有关此信息的信息。我了解一些,但其中大多数是用不同的方法编写的。我只是找不到有关如何通过 return 语句从子进程返回值的足够信息。我责备自己不够努力,但我被困在一个泥泞的水坑里。感谢您提供任何信息。

我的目标(学校作业)是让子进程读取父级的信息。孩子将十个数学计算(加法)从父母收到的每个值,然后将最终值发送回父母以打印到屏幕上。

规则: 1. 不能在子进程中使用命令行参数,只有父进程 2.所有数学计算必须在子进程内。 3. 不需要错误检查。

这是我所拥有的一些代码:

int main(int argc, char **argv){
  char buf[256];
  int pipeCommunication[2];
  pipe(pipeCommunication);

  pid_t pid = fork();

  if(pid == 0){
    //inside child process
    int sum = 0;
    read(pipeCommunication[0], buf, sizeof(buf));
    sum += atoi(buf);
    return sum; //WHY DOES IT NOT RETURN THE VALUE OF SUM?
  }else{
   int sum = 0;
   for(int i = 1; i<argc;i++){
     write(pipeCommunication[0], argv[i], sizeof(argv);
     wait(NULL);
   }
   printf("sum = %d\n", sum); //WHY CANT I SEE THE VALUE OF SUM FROM CHILD?
   return 0; 
  }
}

命令行输入为:./apprun 1 2 3 输出:6 (加 1 + 2 + 3 = 6)

编辑:我意识到也许我的写入或读取函数需要清除以允许将另一个值读入子进程。仍在努力解决这个问题。

编辑:我已经完成了作业,如果有人想查看最终代码,我会在此处发布结果。之后,这个线程就完成了。

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

#define SIZE argc-1

int main(int argc, char **argv)
{
  int   userInput[SIZE];        
  int       temp;                  
  int     uiSize = sizeof(userInput)/sizeof(userInput[0]);    

  int   pipeCom[2];             
  pipe(pipeCom);                  

  printf("CS201 - Assignment 3 Regular - Jonathan Vazquez\n");

  pid_t pid = fork();

  if (pid == 0) {

      int sum = 0;

      close(pipeCom[1]);                              
      for(int i = 0;i < uiSize; i++){
          read(pipeCom[0], &temp, sizeof(temp));      
          sum += temp;                                
          temp = 0;                                   
      }

      return sum;                                     
  }else {

      int sum = 0;                                                  
      for(int i = 1; i < argc; i++){
        userInput[i] = atoi(argv[i]);               
      }

      close(pipeCom[0]);                              
      for(int i = 1; i < uiSize+1;i++){              
          write(pipeCom[1], &userInput[i], sizeof(userInput));    
      }

      int status;
      wait(&status);                                  
      sum = WEXITSTATUS(status);                      
      printf("sum = %d\n", sum);
      return 0;
  }
 }

【问题讨论】:

  • 提示:紧跟在fork 之后,孩子是父母的完全复制品。当时在父级中设置的任何变量也(单独)存在于子级中。在那之后,任何一个进程中的任何更改都对另一个进程不可见,因此您需要一种方法来传达这些更改。
  • 如果第一次通过父母的for循环等待孩子完成,那么write第二次要做什么?
  • @dbush 好的,我假设管道概念有助于在每个进程之间进行传输,对吗?对于这个场景,一个简单的双向连接是否有效? (int pipeCommunication[2];) 还是我需要更多?
  • @aschepler 理想情况下,argv 代表 3 个输入。我在想 for 循环会遍历命令行参数数组,然后每个用户输入都会写入子进程。我必须接受每个输入个体并将其添加到总数中。 wait() 函数位于错误的区域,因为我假设在第一个循环之后,子进程正在终止。我意识到子进程没有收到来自父 for 循环的值。

标签: c pipe fork computer-science


【解决方案1】:

孩子的主函数的返回值(您在此处返回的“总和”)可以作为孩子的退出状态访问。退出状态被限制为 8 位(不是一个完整的整数),因此它通常只用于返回一个有限的错误代码而不是一个值,但它可能对您的目的来说足够大了。

要在父节点中获取子节点的退出代码,您需要传递一个指向等待状态变量的指针,而不是 NULL。将wait(NULL) 行替换为:

int status;
wait(&status);
sum = WEXITSTATUS(status);

或者(建议使用 8 位通常是不够的),您可以创建第二个从子级返回父级的管道,让子级将总和写入该管道并让父级读取它。

【讨论】:

  • 我想在子进程中创建第二个管道,但是,我的导师要求我们使用 return 语句发送值。 “返还金额;”我是否可以假设这是不可能的,因为两个过程的总和变量不同?
  • 这篇文章中显示的代码向您展示了父级如何获取子级从main返回的值。
  • @aschepler 完美,我把它放在子进程中。我进一步阅读并意识到他希望我将它插入到父函数中。我设法得到结果,我将尝试将这些值相加。我还将上面的最终最终结果作为编辑发布,以便其他人以后可以参考。感谢您的帮助!
猜你喜欢
  • 2018-04-05
  • 2018-09-09
  • 2016-03-22
  • 2011-10-11
  • 1970-01-01
  • 2015-11-23
  • 2017-05-30
  • 1970-01-01
相关资源
最近更新 更多