我已经完成了代码的这一部分,可以平稳运行,但是我无法确定所创建的第二个进程是第一个子进程的孙子还是子进程。是这个吗?
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;
}
答案 0 :(得分:2)
在第一个示例中,我们具有以下过程:
Parent
parent()
Child
child1()
child2()
Grandchild
Doesn't so anything
因为第二个fork()
是在子进程中完成的。然后在结果为非零时调用child2()
,这意味着它与调用fork()
的过程相同。由于第二个else
之前没有if
块,因此孙代不会运行任何代码(实际上,它将运行您发布的所有内容之后的代码)。
第二个示例如下:
Parent
parent()
Child 1
child1()
Child 2
child2()
在这种情况下,第二个fork()
在原始进程中执行。
此外,如果child1()
没有退出进程,则子进程1将在第一个if/else
完成后继续执行,因此它将也执行第二个fork()
。然后,您将获得以下内容:
Parent
parent()
Child 1
child1()
Grandchild
child2()
Child 2
child2()
答案 1 :(得分:2)
首先,这些不一样。在第二段代码中,从第一个if (fork() != 0)
创建的父级和子级都将调用第二个if (fork() == 0)
(创建另外两个子进程,其中一个是孙代)。
在第一段代码中,仅由if (fork() != 0)
创建的子级将调用第二个if(fork() != 0)
。在两个示例中,都有一个孙子进程。
此外,在第一段代码中,您将child2(array,N)
称为父级(也是第一个子级)。这样,您最终会毫无理由地分叉。如果您希望孩子打电话给if (fork() == 0)
(因此是真正的孙子),则应该执行child2(array,N)
。现在,孙子进程刚刚退出。
这是一棵显示叉子的树。
第一部分代码的树。请注意,在树上的Evert拆分表示一个fork调用。当我们上升时,我们是子进程,而当我们下降时,我们是fork的父进程。我在树中添加了延迟以显示等待。
获得相同结果的原因是,父进程调用的第二个child2
在打印结果之后发生。
此外,在parent
中,您仅等待第一个孩子,但使用第二个孩子的结果。您还应该向child1
添加一些等待逻辑。
我建议您使用以下内容
if (fork() != 0)
parent(array,N);
else {
child1(array,N);
if(fork() == 0)
child2(array,N);
}
在这里,child2
被称为孙进程。