【问题标题】:What will be the difference in values after fork calls for child and parent process?在 fork 调用子进程和父进程后,值会有什么不同?
【发布时间】:2016-02-26 19:55:37
【问题描述】:

我无法弄清楚它是如何工作的。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;
}

【问题讨论】:

  • 对我来说很好:Before Fork pid= 31955,glb=101,var=89 pid= 31954,glb=100,var=88 你得到什么输出表明它没有?
  • 你错了孩子不输出“glb=101,var=89”?它确实输出。
  • 是的,现在可以了,我关闭了终端并再次运行它,现在它工作正常了。不过我有一个问题,它们的 pid 是按递增顺序排列还是也可以变化。谢谢。
  • pids 在 windows 和 linux 上隐约增加,但它们被重用,因此不能真正保证重用。

标签: c fork system-calls


【解决方案1】:

当进程分叉时,它的地址空间被克隆,因此会有一个带有主线程堆栈的段(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。

【讨论】:

    猜你喜欢
    • 2020-01-22
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    • 2021-02-10
    • 1970-01-01
    相关资源
    最近更新 更多