进程概念--地址空间

文章通过示例代码展示了在Linux环境下,父子进程共享同一虚拟地址但内容可能不同的现象,解释了这是由于虚拟地址映射到不同的物理地址导致的。在C/C++程序中,我们看到的地址都是虚拟地址,而实际的物理地址由操作系统管理并转换。进程的地址空间确保了每个进程独立的视图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

研究背景:

  • kernel 2.6.32 

  • 32位


回顾程序地址空间 

 上段代码感受一下:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int g_val = 0;
int main()
{
    pid_t id = fork();
    if (id < 0)
    {
        perror("fork");
        return 0;
    }
    else if (id == 0)
    { // child
        printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
    }
    else
    { // parent
        printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
    }
    sleep(1);
    return 0;
}

观察输出结果:发现父子进程的打印出的地址都是相同的 0x601058 ,这是因为父子并没有堆变量进行任何的修改。 下面稍微变更一下代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int g_val = 0;
int main()
{
    pid_t id = fork();
    if (id < 0)
    {
        perror("fork");
        return 0;
    }
    else if (id == 0)
    { // child,子进程肯定先跑完,也就是子进程先修改,完成之后,父进程再读取
        g_val = 100;
        printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
    }
    else
    { // parent
        sleep(3);
        printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
    }
    sleep(1);
    return 0;
}

 

 发现父子进程时在打印时是同一块地址,但是g_val的值却不一样,则可以得出结论

  • 变量内容不一样,所以输出的值绝不是同一个变量
  • 但地址是一样的,所以说明这里的地址绝不是物理地址
  • 在Linux下我们叫这种地址为虚拟地址
  • 我们C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS进行管理

OS必须负责将虚拟地址转化成物理地址!!


进程地址空间

所以之前说的程序地址空间是不准确的,如图! 

上面的图就足矣说名问题,同一个变量,地址相同,其实是虚拟地址相同,内容不同其实是被映射到了不同的物理地址!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Obto-

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

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

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

打赏作者

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

抵扣说明:

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

余额充值