【Linux系统】程序虚拟地址空间(重要)




在这里插入图片描述



一、引入:一个诡异的例子


我们在程序中 fork 创建一个子进程:

让子进程死循环打印自己的 pid、ppid,还有全局变量 gval 及其地址,同时子进程每轮 gval++

让父进程死循环打印自己的 pid、ppid,还有全局变量 gval 及其地址

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

int gval = 100;

int main() {
    printf("我是一个进程, pid :%d, ppid :%d\n", getpid(), getppid());

    pid_t id = fork();
    
    if (id == 0) {
        // child
        while(1) {
            printf("我是子进程, pid :%d, ppid :%d, gval:%d, &gval:%p\n", getpid(), getppid(), gval, &gval);
            gval++;
            sleep(1);
        }
    } 
    else {
        // parent
        while(1) {
            printf("我是父进程, pid :%d, ppid :%d, gval:%d, &gval:%p\n", getpid(), getppid(), gval, &gval);
            sleep(1);
        }
    }
}

运行结果如下:

在这里插入图片描述


子进程确实按程序每轮 gval++,而父进程的 gval 一直保持 100,这些都正常,父子进程都按照自己的代码逻辑运行。

但是,你有没有发现,父子进程的 gval 的地址是一样的!!!!!

为什么?因为进程具有独立性,父子进程中的 gval 都以自己的代码逻辑变化,他们指向的却还是 “同一个 gval” ?,那如果指向同一个 gval ,那为什么父子进程的 gval 不同值??

这就涉及到虚拟地址空间了,这里暂时可以输出一个结论:此处父子进程打印出来的 gval 的地址是虚拟地址!,绝非以前学习所理解的 物理内存地址。




二、认识进程地址空间

下面这张图展示的就是进程地址空间:其中划分了几块不同的分区。

在我们学习C语言时,很多网课或博客都会以下面这张图讲解C语言的内存空间分布,讲解不同类型数据的存储位置。

但是,在一些C语言的教材中却看不到这张图,这是因为下面这张图不是程序地址空间,而是进程地址空间,是系统范畴的,而不属于语言范畴的。






进一步认识进程地址空间:大富翁的例子


        某个国家有个大富翁,该大富翁的钱被以一种顺序排序着,就是所有的钱都有对应编号,想要用钱时直接在机器上输入某某编号就能取出对应位置编号的钱。这个大富翁有很多子女,大富翁允许这些子女取自己的钱使用,当然也是通过输入编号取出对应位置一定数额的钱。然而有一天,两个儿子打起来了,原因是大儿子想要取出编号为 1 的 100 元,而二儿子在第二台机器上也想要取出编号为 1 的 100 元,这就造成了冲突,编号为 1 的 100 元只有一张,不能同时从两个机器中取出,因此他们就产生了冲突。

        而在平行宇宙中,存在另一个十亿资产大富翁,他在外头有很多私生子,大富翁给他们每个人画了一个大饼:”你爹我有十个亿,你可以使用我的十个亿,但使用前需要向我申请“。可是!各个私生子之间互相不知道对方的存在,都以为自己是大富翁的唯一后代,因此都认为自己”已经拥有了“自己父亲的全部十亿资产!!当某个私生子向父亲要钱时,大富翁就在自己余额中取钱给这个私生子。但是私生子们不知道,其实父亲的资产只剩下一亿了,另外9亿是被其他私生子霍霍光的,可是由于各个私生子都以为自己拥有的是父亲的十亿资产……

因此,在私生子的认知里,自己拥有父亲所有资产,实际上父亲的资产已经没有这么多了


在这个例子中

第一个大富翁的资产就是实际的物理内存大小,儿女就是

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值