fork函数与子进程

17 篇文章 0 订阅

1、共享正文段

    下面是用fork创建一个子进程的例子(参考资料[1]程序清单8-1):

#include <stdio.h>
#include <unistd.h>
int glob = 6; // external variable in initialized data
char buf[] = "a write to stdout\n";
int main(void){
        int var; // automatic variable on the stack
        pid_t pid;
        var = 88;
        if(write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
                printf("write error\n");
        printf("before fork\n"); //we don't flush stdout
        if((pid = fork()) < 0)
                printf("write error");
        else if(pid == 0) { // child
                glob++;
                var++;
        }
        else { // parent
                sleep(2);
        }
        printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
        return(0);
}

    根据父/子进程的注释,很自然的以为else if(pid==0){}中的代码属于子进程,而else{}中的代码属于父进程。这样就有个疑惑:除了else if(pid==0){}和else{}之外的printf("pid=%d, ...")是属于谁的呢?

    其实,上面的理解是错的。根据参考资料[1]P172的描述:“子进程和父进程继续执行fork调用之后的指令”。也就是说,不管是else if(pid==0){}还是else{},都是父子进程所共有的,只是在子进程中fork的返回值pid=0,因此会执行else if(pid==0){}一段,而父进程中fork的返回值pid>0,因此执行else{}一段。至于printf(“pid=%d, ...”),父子进程都会执行!

    参考资料[1]P153提到,正文段(CPU执行的指令部分)是可以共享的。参考资料[1]P172提到:父、子进程共享正文段。

    下面是上面例子的运行结果:

a write to stdout
before fork
pid = 3204, glob = 7, var = 89
pid = 3203, glob = 6, var = 88

    由此可见,printf("pid=%d,....")被执行了2次,一次是在父进程中执行,pid=3203,;另外一次是在子进程中执行,pid=3204。从而印证了上面的说法。

    然而,fork()以上的write()只被执行1次,说明父子进程共享的正文段是从fork()之后开始的。

2、数据段、堆栈

    参考资料[1]提到,子进程复制父进程的数据段、堆、栈的副本,但是不共享。也就是说子进程只是将父进程的数据段、堆、栈父子了一份到自己的存储空间了,并非和父进程共享这些空间。由上面的执行结果可以知道,父子进程分别有自己的glob、var变量的存储空间,而且子进程的glob、var变量的初始值是从父进程中复制进来的。

参考资料

[1]《UNIX环境高级编程》.2nd

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OneSea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值