简体   繁体   English

fork()函数如何在此程序中工作?

[英]How fork() function works in this program?

I'm having some trouble with this program. 我在使用该程序时遇到了麻烦。 I know what a fork() function does. 我知道fork()函数的作用。 It is used to create a new process from an existing process. 它用于从现有流程创建新流程。 The new process is called the child process, and the existing process is called the parent. 新流程称为子流程,现有流程称为父流程。 The parent returnes the child's pid and the child returns 0. That said, I find hard to understand what the two fork functions do in this program. 父级返回孩子的pid,子级返回0。也就是说,我很难理解这两个fork函数在程序中的作用。

#include <unistd.h>
#include <stdio.h>

int main()
{
    int i,y,x=1;
    for (i=0;i<4;i++)
        if(x && fork())
        {
            y = i;
            x = 0;
        }
    if (x) y = i;
    fork();
    printf("%i\n",y);
}

First assert that: fork don't fail. 首先断言:fork不会失败。 That is not true, but more simple 那不是真的,但是更简单

if (x && fork()) -> is true if x == 1 and if the fork return for the father then false. 如果(x && fork())->如果x == 1,并且叉子返回父亲,则为true。 So the child will create a child too (except the last one) but the father just create one child. 因此,孩子也会创建一个孩子(最后一个孩子除外),而父亲只会创建一个孩子。

After the loop you have 1 + 4 new process. 循环后,您将拥有1 + 4个新进程。 This 5 processus do the last fork(), you have 10 process. 这5个进程执行最后一个fork(),您有10个进程。

The output result is not deterministic because of the scheduling of tasks. 由于任务的调度,输出结果不确定。

Original process opens up a process when it enters the loop's if . 当原始进程进入循环的if时,它将打开一个进程。 The child does not enter the if since fork() == 0 . 由于fork() == 0 ,孩子不会输入if Now the parent has x == 0 and no longer enters the following iterations' if s (short circuit && prevent fork s). 现在,父对象的x == 0并且if s(短路&&防止fork ), if不再进入后续迭代。

note: short circuit if(x && fork()) prevents from forking twice since x == 0 => no need to evaluate fork() (true for all processes that forked once). 注意:短路if(x && fork())可以防止两次分叉,因为x == 0 =>无需求值fork() (对于所有一次分叉的进程为true)。 A process that forked once never enters loop's if because x == 0 from that point on. if从该点开始x == 0if一次分叉的进程永远不会进入循环。

What you get is each loop value twice because each new process forks once the following iteration and outside the loop right before the print. 您得到的是每个循环值两次,因为每个新进程在下一次迭代时派生一次,并在打印之前在循环外进行。 There are no forks other than the first for each spawned process in the loop. 循环中每个生成的进程都没有第一个分支。

#include <unistd.h>
#include <stdio.h>

int main()
{
    int i,y,x=1;
    for (i=0;i<4;i++)
        if(x && fork()) // only un-forked process (x=1) executes fork()
        {
            // only parent process (fork() != 0) execute this
            y = i;
            x = 0;
        }
    if (x) y = i; // set up i=4 for last forked process (has x=1)
    fork();
    printf("%i\n",y);
}

The process spawning process would look something like this: 生成过程如下所示:

分叉过程,并且在最后一次打印之前

tip: When investigating code like this you can add output statements ( printf ) or use a debugger. 提示:研究此类代码时,可以添加输出语句( printf )或使用调试器。

Actually you can learn something from this program, when you look at the pids the forks return and estimate from that, which fork produces what output: 实际上,您可以从该程序中学到一些知识,当您查看叉子返回的pid并据此估算时,哪个叉子会产生什么输出:

#include <unistd.h>
#include <stdio.h>

int main()
{
    int i,y,x=1;
    pid_t p,c;
    for (i=0;i<4;i++)
        if(x && 0 != (p=fork()))
        {
            y = i;
            c = p;
            x = 0;
        }
    if (x) y = i;
    p=fork();
    printf("%i %d %d\n",y, p, c);
}

For example I get this output: 例如,我得到以下输出:

0 24413 24412
0 0 24412
2 24417 24416
1 24415 24414
1 0 24414
3 24419 24418
2 0 24416
3 0 24418
4 24420 0
4 0 0

The first line is the child of the first child, the next line is the first child itself and so on. 第一行是第一个孩子的孩子,下一行是第一个孩子本身,依此类推。 The last line is the parent. 最后一行是父级。

Think over that and you can learn how fork works. 考虑一下,您将了解fork的工作原理。

Err, sorry, I was completely wrong, nearly: fork returns a positive pid to the parent, not to the child of course. 错误,对不起,我几乎完全错了:fork向父级(而不是子级)返回一个正pid。 So each line with positive p and c is the parent and so on. 因此,p和c为正的每一行都是父级,依此类推。 I leave the rest to figure out for you. 我把剩下的留给你解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM