fork调用子进程和父进程后,值的差异是什么?

时间:2016-02-26 19:55:37

标签: c fork system-calls

我无法弄清楚它是如何工作的。fork系统调用将父进程拆分为两个进程,它为子进程返回零。根据我的输出应该是glb = 101.var = 89进行子进程。但是我错了。有人可以解释一下它的工作原理吗?

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

int glb=100;
int main()
{
    int pid;  
    int var =88;
    printf ("Before Fork\n");
    pid=fork();
    if(pid <0)
    {
        perror("fork");
        exit(1);
    }
    if(pid ==0) /**child**/
    {
        glb++;var++;
    }
    else 
    {
        sleep(5);
    }

    printf("pid= %d,glb=%d,var=%d\n",getpid(),glb,var);
    return 0;
}

1 个答案:

答案 0 :(得分:2)

当进程分叉时,它的地址空间正在被克隆,因此会有一个主线程堆栈(var所在的位置),但引用它的两个进程:

            +-------+
parent ---> |  var  | <--- child
            +-------+

同样适用于glb所在的数据段。

当其中任何一个尝试修改它时,会生成写时复制页面错误并且操作系统正在复制数据段:

            +--------+  var++
parent ---> |   88   | <--- child
            +--------+

Handle cow-fault:

            +--------+             +--------+
parent ---> |   88   |  child ---> |   88   |
            +--------+             +--------+

Restart from same instruction:

            +--------+        var++ +--------+
parent ---> |   88   |  child ----> |   88   |
            +--------+              +--------+

            +--------+       printf +--------+
parent ---> |   88   |  child ----> |   89   |
            +--------+              +--------+

所以孩子应该打印101和89,而父母应该打印100和88。