【问题标题】:How to get return value from CHILD PROCESS?如何从子进程中获取返回值?
【发布时间】:2010-01-27 11:57:08
【问题描述】:

程序计算从 1 到 N 的数字之和。 子进程计算偶数的总和。 父进程计算奇数的总和。 我想在父进程中获取子进程的返回值。我该怎么做

#include<stdio.h>
#include<errno.h>
#include<unistd.h>
#include<stdlib.h>
#include<fcntl.h>

int main()
{
    int N;
    int id;
    int fd_result;;

    printf("Enter N till which you want the sum: \n");
    scanf("%d",&N);
    if ((fd_result=creat("result", 600))== -1)
    {
        perror("Error creating file");
        exit(1);
    }
    if ((fd_result=open("result",O_TRUNC | O_RDWR)) == -1)
    {
        perror("Error Opening file");
        exit(1);
    }
    if ((id=fork())<0)
    {
        perror("Error occurred forking....!");
        exit(errno);
    }
    if (id == 0)
    {
        int i;
        int sum=0;
        for (i=0;i<=N;i=i+2)
            sum+=i;
        printf("Child sum: %d",sum);
        if (write(fd_result,&sum,sizeof(int))==-1) perror("Error writing to file");
        _exit(0);
    }


    if (id > 0)
    {
        int i;
        int sum=0;
        int sum_odd;
        for (i=1;i<=N;i=i+2)
            sum+=i;
        lseek(fd_result,0,SEEK_SET);
        read(fd_result,&sum_odd,sizeof(int));
        printf("\nThe sum is: %d",sum+(int)sum_odd);
    }

    close(fd_result);
    return 0;
}

请告诉我如何获取子进程的返回值?

【问题讨论】:

    标签: c linux unix gcc fork


    【解决方案1】:

    您要查找的是wait()waitpid()

    【讨论】:

    • 我如何实际使用它?我无法得到它。实际上这是我第一次编写 fork() 程序...请帮助
    • 在父调用waitpid(-1, &status, 0);
    【解决方案2】:

    TLDR

    int wstatus;
    waitpid(<pid>, &wstatus, 0); // Store proc info into wstatus
    int return_value = WEXITSTATUS(wstatus); // Extract return value from wstatus
    

    参考

    waitpid 的手册页显示其类型签名是:

    pid_t waitpid(pid_t pid, int *stat_loc, int options);
    

    它还指出我们可以使用stat_loc 参数存储进程信息:

    如果参数stat_loc的值不是空指针,则信息应存储在stat_loc指向的位置

    stat_val 参数是stat_loc 指向的整数值。

    然后我们使用WEXITSTATUS(wstatus) 从流程中提取我们的返回值。

    WEXITSTATUS(stat_val): 如果 WIFEXITED(stat_val) 的值非零,则此宏计算子进程传递给 _exit() 或 exit() 的状态参数的低 8 位,或子进程的值从 main() 返回。

    【讨论】:

      【解决方案3】:

      哎呀!这不是 bash!总之……

      产生一个进程的原因是为了继续主流程,同时做一些不影响它的事情。我正在浏览 10k 图像的目录,并移出重复的图像。我将比较代码放在一个函数和子进程中。它非常快。

      取回值的方法是创建一个管道,在其上回显一个值,然后读取管道:(警告!以下代码可能不起作用,它只是显示一个工作管道)

      mkfifo pipe
      moved=0
      # Use imageMagick 'compare' to find files with zero difference:
      comPare () { 
       if [[ ! $(compare -metric AE $1 $2) ]]; then 
          mv $2 moved;
          echo 1 > pipe;
        else echo 0 > pipe
        fi
      }
      
      # For every file in the dir, compare it to every other one:
      for file1 in $( ls *.bmp | head -n $(( $( ls *.bmp | wc -l) - 1)); do
      for file2 in $( ls *.bmp | tail -n $(( $( ls *.bmp | wc -l) - 1)); do
          comPare file1 file2 &
          moved=$(( $(cat pipe) + 1 ))
      done
      done
      rm pipe
      echo "Moved $moved files"
      

      到目前为止,唯一的问题是我正在使用 USB 驱动器,并且权限阻止我创建管道。除此之外……

      【讨论】:

        【解决方案4】:

        就像 dtmilano 所说,您应该使用 wait 或 waitpid,这取决于或需要。

        但也许你应该把你的程序分成两部分,然后用 exec 执行子程序。当您进行 fork 时,您的子进程收到 pid 等于 0,我不知道您是否尝试等待 pid 为 0 的进程信号会正常工作。

        无论如何你都可以通过你的子进程通过退出计算的值,虽然这不是最好的方法。

        【讨论】:

          【解决方案5】:

          如果您想保留返回值以指示成功或失败退出状态,您可以在分叉之前调用pipe(2) 以在父子之间建立单独的通道。

          【讨论】:

            猜你喜欢
            • 2018-09-09
            • 2010-12-07
            • 1970-01-01
            • 2018-12-01
            • 1970-01-01
            • 2021-02-24
            • 1970-01-01
            • 2019-08-04
            • 2012-02-20
            相关资源
            最近更新 更多