首页 > 解决方案 > 过程 - 子或孙?

问题描述

我有这部分代码,运行平稳,但我无法确定创建的第二个进程是第一个子进程的孙子进程,还是只是一个子进程。这是 :

if (fork() != 0)
    parent(array,N);
else {
    child1(array,N);
    if(fork() != 0) 
        child2(array,N);
}

与此相同:

if (fork() != 0)
    parent(array,N);
else {
    child1(array,N);
}

if (fork() == 0)
    child2(array,N);

因为我得到了相同的结果。该程序有一个数组,父计算数组的第一个 1/3 的最大值,第一个孩子计算第二个 1/3,第二个孩子计算第三个。父级从子级的管道中获取结果并打印出来。我在上面展示的 2 个版本运行相同。

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

int pfd1[2],pfd2[2]; // pfd[1] gia to prwto paidi , pfd[2] gia to deutero paidi

void parent(int array[],int N) {



    int i;
    int max_p;
    int child1_max,child2_max;        //auto pou 8a steilei

    max_p=array[0];      // <============================================================================

    close(pfd1[1]); //no writing by the parent
    close(pfd2[1]); //no writing by the parent

    for(i=0;i<N/3;i++) {

        if(array[i]>max_p) {
            max_p=array[i];
        }
    }

    waitpid(-1, NULL, 0);   /* Wait my child process */

    read(pfd1[0],&child1_max,sizeof(int)); //get 1st child's max_c
    close(pfd1[0]);

    read(pfd2[0],&child2_max,sizeof(int)); //get 1st child's max_c
    close(pfd2[0]);

    printf("1st child_max is %d\n",child1_max); 
    printf("2nd child_max is %d\n",child2_max);
    printf("parents max is %d\n",max_p);

    /*if(max_p>child_max) {
        printf("max is %d (was in parent)\n",max_p);
        printf("max of child is %d\n",child_max);
    }else {
        printf("max is %d (was in child)\n",child_max);
        printf("max of parent is %d\n",max_p);
    }*/


}


void child1(int array[],int N) {
    int i;

    int max_c=array[N/2];    // <============================================================================

    close(pfd1[0]); // No reading by child

    for(i=N/3;i<(2*N)/3;i++) {

        if(array[i]>max_c) {
            max_c=array[i];
        }
    }

    write(pfd1[1],&max_c,sizeof(int));
    close(pfd1[1]);
}

void child2(int array[],int N) {
    int i;

    int max_c=array[(2*N)/3];  // <============================================================================

    close(pfd2[0]); // No reading by child


    for(i=(2*N)/3;i<N;i++) {

        if(array[i]>max_c) {
            max_c=array[i];
        }
    }

    write(pfd2[1],&max_c,sizeof(int));
    close(pfd2[1]); 



}

int main(void) {

    int array[]={111,1222,10,392,3211,3,2,50,8};
    int N=sizeof(array)/sizeof(int);

    //printf("\n %d \n",N);

    if (pipe(pfd1) < 0)
    {
        perror("pipe()");
        exit(1);
    }

    if (pipe(pfd2) < 0)
    {
        perror("pipe()");
        exit(1);
    }

    if (fork() != 0)
        parent(array,N);

    else {
        child1(array,N);

        //if(fork() != 0) 
        //  child2(array,N);
    }

    if (fork() == 0)
        child2(array,N);

    return 0;

}

标签: cprocessfork

解决方案


首先,这些不一样。在第二段代码中,从第一段创建的父进程和子进程if (fork() != 0)都将调用第二段代码if (fork() == 0)(创建另外两个子进程,其中一个是孙子进程)。在第一段代码中,只有由创建的孩子if (fork() != 0)会调用第二段if(fork() != 0)。在这两个示例中都有一个孙进程。

此外,在第一段代码中,您调用child2(array,N)父级(好吧,作为第一个子级)。通过这样做,你最终会无缘无故地分叉。if (fork() == 0)如果您希望孩子打电话child2(array,N)(从而成为真正的孙子),您应该这样做。现在,孙子进程刚刚退出。

这是一棵展示叉子的树。第一段代码的树。注意,树上的 evert split 代表一个 fork 调用。当我们上升时,我们是子进程,当我们下降时,我们是 fork 的父进程。我在树中添加了延迟以显示等待。 在此处输入图像描述

第二段代码的树: 在此处输入图像描述

您获得相同结果的原因是因为child2父进程调用的第二个发生在您打印结果之后。

此外,parent您只等待第一个孩子,但您使用第二个孩子的结果。您还应该将一些等待逻辑添加到child1.

我建议你使用以下

if (fork() != 0)
    parent(array,N);
else {
    child1(array,N);
    if(fork() == 0) 
        child2(array,N);
}

这有以下树。 在此处输入图像描述

在这里,child2称为孙进程。


推荐阅读