进程 - child 还是 grandchild?
Process - child or grandchild?
我有这部分代码,运行顺利,但我不知道创建的第二个进程是第一个 child 的大 child,还是只是 child过程。这是:
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);
因为我得到了相同的结果。该程序有一个数组,parent 计算数组的第一个 1/3 的最大值,第一个 child 第二个 1/3 和第二个 child 第三个。 Parent 从 children 的管道中获取结果并打印出来。对于我上面展示的 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;
}
在第一个例子中我们有以下过程:
Parent
parent()
Child
child1()
child2()
Grandchild
Doesn't so anything
因为第二个fork()
是在子进程中完成的。然后当结果为非零时它调用 child2()
,这意味着它是调用 fork()
的同一个进程。由于第二个 if
没有 else
块,孙子没有 运行 任何代码(实际上,它会 运行 你发布的所有代码之后的代码)。
第二个例子如下:
Parent
parent()
Child 1
child1()
Child 2
child2()
在这种情况下,第二个fork()
在原来的流程中执行。
此外,如果 child1()
不退出进程,子进程 1 将在第一个 if/else
完成后继续执行,因此它 也会 执行第二个fork()
。然后你会得到以下内容:
Parent
parent()
Child 1
child1()
Grandchild
child2()
Child 2
child2()
首先,它们是不一样的。在第二段代码中,从第一个 if (fork() != 0)
创建的 parent 和 child 都将调用第二个 if (fork() == 0)
(创建另外两个 child 进程,其中一个是一个伟大的 child)。
在第一段代码中,只有if (fork() != 0)
创建的child会调用第二个if(fork() != 0)
。在这两个例子中都有一个宏大的child过程。
此外,在第一段代码中,您将 child2(array,N)
称为 parent(嗯,作为第一个 child)。通过这样做,你最终会无缘无故地分叉。如果您希望 child 调用 child2(array,N)
(从而成为真正的 grandchild),您应该执行 if (fork() == 0)
。现在,grandchild 进程刚刚退出。
这是一棵树来展示叉子。
第一段代码的树。请注意,树上的 eversplit 代表一个 fork 调用。我们往上走就是child进程,往下走就是fork的parent进程。我在树中添加了延迟以显示等待。
您得到相同结果的原因是因为 parent 进程调用的第二个 child2
发生在您打印结果之后。
此外,在 parent
中,您只等待第一个 child,但您使用第二个 child 的结果。您还应该向 child1
.
添加一些等待逻辑
我建议你使用以下
if (fork() != 0)
parent(array,N);
else {
child1(array,N);
if(fork() == 0)
child2(array,N);
}
这里,child2
被称为grandchild进程。
我有这部分代码,运行顺利,但我不知道创建的第二个进程是第一个 child 的大 child,还是只是 child过程。这是:
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);
因为我得到了相同的结果。该程序有一个数组,parent 计算数组的第一个 1/3 的最大值,第一个 child 第二个 1/3 和第二个 child 第三个。 Parent 从 children 的管道中获取结果并打印出来。对于我上面展示的 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;
}
在第一个例子中我们有以下过程:
Parent
parent()
Child
child1()
child2()
Grandchild
Doesn't so anything
因为第二个fork()
是在子进程中完成的。然后当结果为非零时它调用 child2()
,这意味着它是调用 fork()
的同一个进程。由于第二个 if
没有 else
块,孙子没有 运行 任何代码(实际上,它会 运行 你发布的所有代码之后的代码)。
第二个例子如下:
Parent
parent()
Child 1
child1()
Child 2
child2()
在这种情况下,第二个fork()
在原来的流程中执行。
此外,如果 child1()
不退出进程,子进程 1 将在第一个 if/else
完成后继续执行,因此它 也会 执行第二个fork()
。然后你会得到以下内容:
Parent
parent()
Child 1
child1()
Grandchild
child2()
Child 2
child2()
首先,它们是不一样的。在第二段代码中,从第一个 if (fork() != 0)
创建的 parent 和 child 都将调用第二个 if (fork() == 0)
(创建另外两个 child 进程,其中一个是一个伟大的 child)。
在第一段代码中,只有if (fork() != 0)
创建的child会调用第二个if(fork() != 0)
。在这两个例子中都有一个宏大的child过程。
此外,在第一段代码中,您将 child2(array,N)
称为 parent(嗯,作为第一个 child)。通过这样做,你最终会无缘无故地分叉。如果您希望 child 调用 child2(array,N)
(从而成为真正的 grandchild),您应该执行 if (fork() == 0)
。现在,grandchild 进程刚刚退出。
这是一棵树来展示叉子。
第一段代码的树。请注意,树上的 eversplit 代表一个 fork 调用。我们往上走就是child进程,往下走就是fork的parent进程。我在树中添加了延迟以显示等待。
您得到相同结果的原因是因为 parent 进程调用的第二个 child2
发生在您打印结果之后。
此外,在 parent
中,您只等待第一个 child,但您使用第二个 child 的结果。您还应该向 child1
.
我建议你使用以下
if (fork() != 0)
parent(array,N);
else {
child1(array,N);
if(fork() == 0)
child2(array,N);
}
这里,child2
被称为grandchild进程。