与fork()混淆

时间:2011-10-03 02:05:21

标签: c fork

我很难理解fork()命令在不同场景下的作用。以下是我的书中的一些示例代码:

int main() {
    int a = 12;
    int b = 9;
    int fid = fork();

    if (fid == 0) {
        a++;
    }
    else {
        wait(NULL);
        b = b - 5;
    }

    printf("program exit. a = %d, b = %d\n", a, b);
    return 0;
}

在这种情况下,有人可以告诉我fork()命令正在做什么,并且可能会提供一些示例来澄清吗?

4 个答案:

答案 0 :(得分:12)

                 [main]
                 a = 12
                 b = 9

                 fork()
                   |
                   |
    +--------------+--------------+
    |                             |  
    |                             |
[parent]                       [child]

fid = 1234                     fid = 0
wait(NULL)                     a++
   ...                         printf("a = 13, b = 9");
   ...                         return 0
   ...                         <exit>
b = b - 5
printf("a = 12, b = 4");
return 0
<exit>

执行fork()后,程序有两个副本。每个进程都有自己的变量副本,因此现在有两个a,两个b等。两个程序之间的唯一区别是从{{1}返回的值}:在子进程中fork()返回0;在父进程中,它返回子进程的PID。

子进程增加fork(),打印aa的值,然后退出。

父进程首先等待子进程终止。只有在孩子完成后才会继续,从b减去5,打印出ba,然后退出。

b确保子进程的打印输出始终位于父进程之前,因此您将始终以可靠的顺序获得相同的输出。没有它你将无法依赖两个打印输出的顺序。它们将是相同的消息,只是以不可预测的顺序。

答案 1 :(得分:4)

  1. a设为12,b设为9.

  2. fork被调用,我们现在有两个过程。

  3. 父级获取子级的PID,并转到else子句。孩子得0,然后转到if子句。

  4. 父母等待孩子完成。

  5. 儿童递增a的副本。因此a现在在孩子中为13,在父母中为12。

  6. 孩子退出,输出139

  7. 家长从b的副本中减去5,因此b现在在家长中为4。

  8. 家长退出,输出124

  9. 请注意,fork之后的子项和父项的确切执行顺序无法保证,但它不会更改结果,因为父项在执行任何操作之前等待子项完成。

    另外,请注意两个进程正常退出是不好的做法。当一个进程正常退出时,它会运行清理处理程序,这可能会混淆其他进程,例如通过更改共享文件描述上的文件位置,导致数据损坏。

答案 2 :(得分:3)

当您致电fork()时,整个过程(包括所有内存/变量等)都会重复。

fork调用之后,每个进程都拥有自己的ab副本,分别以129开头。

进程0将增加它自己的a副本。过程1将减少(由5)它自己的b

副本

所以他们应该打印:

Process 0: a = 13, b = 9
Process 1: a = 12, b = 4

答案 3 :(得分:0)

它的o / p会是 父:: a = 12,b = 4 孩子:: a = 13,b = 9

因为两个进程同时执行但两者都有不同的局部变量副本a,b 所以局部变种。受一个流程影响的流程将不会被另一个流程看到,因为两个流程都在处理他们自己的副本