了解C中的分叉

时间:2010-11-11 00:25:02

标签: c unix fork

我在理解以下简单的C代码时遇到了一些麻烦:

int main(int argc, char *argv[]) {
    int n=0;
    fork();
    n++;
    printf("hello: %d\n", n);
}

我目前对fork的理解是,从该代码行开始,它将把剩下的代码拆分为2,它将并行运行,直到“没有更多代码”执行为止。 / p>

从那个棱镜,fork之后的代码将是:

A)

    n++;                       //sets n = 1
    printf("hello: %d\n", n);  //prints "hello: 1"

b)中

    n++;                       //sets n = 2
    printf("hello: %d\n", n);  //prints "hello: 2"

然而,会发生的是印刷

hello: 1

为什么?

编辑:只是现在我发现,与线程相反,进程不共享相同的内存。是对的吗?如果是,那就是原因。

7 个答案:

答案 0 :(得分:7)

在fork()之后,你有两个进程,每个进程都有自己的“n”变量。

答案 1 :(得分:3)

fork()启动一个新进程,不共享变量/内存位置。 它与在shell中执行./yourprogram两次的情况非常相似,假设程序执行的第一件事就是分叉。

答案 2 :(得分:2)

在fork()调用结束时,两个进程可能都引用了n的相同副本。但是在n ++中,每个都有自己的副本,n = 0。在n ++的最后; n在两个过程中都变为1。 printf语句输出该值。

答案 3 :(得分:1)

实际上你会产生一个相同程序的新进程。这不是封闭式的东西。您可以使用管道在父级和子级之间交换数据。

答案 4 :(得分:1)

您确实在编辑中回答了自己的问题。

答案 5 :(得分:1)

系统调用多于执行线程:forked也是数据空间。此时你有两个 n 变量。

所有这些都有一些有趣的事情:

  • fork()的程序必须考虑未写入的输出缓冲区。它们可以在fork之前刷新,或者在fork之后清除,或者程序可以_exit()而不是exit()以至少避免在退出时自动缓冲区刷新。
  • Fork通常使用 copy-on-write 实现,以避免不必要地复制不会在子级中使用的大型数据内存。
  • 最后,在大多数当前的Unix版本中,一个替代的调用 vfork()已经恢复,在它引入i 4.0BSD之后消失了一段时间。 Vfork()不会假装复制数据空间,因此实现可能比copy-on-write fork()更快。 (它在Linux中的实现可能不是因为速度原因而是因为一些程序实际上依赖于vfork()语义。)

答案 6 :(得分:1)

检查这段代码,一切都应该更清楚(如果你不知道某个函数是什么,请参阅手册页):

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

int count = 1;

int main(int argc, char *argv[]) {

    // set the "startvalue" to create the random numbers
    srand(time(NULL));
    int pid;

    // as long as count is <= 50
    for (count; count<=50; count++) {

        // create new proccess if count == 9
        if (count==9) {
            pid = fork();
            // reset start value for generating the random numbers
            srand(time(NULL)+pid);
        }

        if (count<=25) {
            // sleep for 300 ms
            usleep(3*100000);
        } else {
            // create a random number between 1 and 5
            int r = ( rand() % 5 ) + 1;
            // sleep for r ms
            usleep(r*100000);
        }

        if (pid==0) {
            printf("Child:  count:%d    pid:%d\n", count, pid);
        } else if (pid>0) {
            printf("Father: count:%d    pid:%d\n", count, pid);
        }
    }


    return 0;
}

快乐的编码; - )