Linux系统编程-进程地址空间

一. 概念

我们平时在写C/C++程序时,所看到的地址其实不是实际的物理内存,而是进程(虚拟)地址空间。每一个进程在创建的时候,系统都会给一个独立的进程地址空间,和一个页表,这个页表负责把虚拟地址映射到物理内存地址。

二. 代码验证

如图所示,父子进程都各自有自己的进程地址空间和页表子进程创建时,子进程的进程地址空间和页表会以父进程为模板初始化,默认跟父进程共享数据和代码(如代码1)

// 代码1
#include<stdio.h>
#include<unistd.h>
int main()
{
    int a = 0;
    pid_t ret = fork();
    if (ret < 0)
    {
        perror("fork");
    }
    else if (ret)
    {
        printf("parent[%d] --> a[%p] --> %d\n", getpid(), &a, a);
    }
    else
    {
        printf("child[%d] --> a[%p] --> %d\n", getpid(), &a, a);
    }
    return 0;
}

在这里插入图片描述

当父进程或者子进程的数据发生改变时,子进程会发生写时拷贝,程序地址不变,会改变对应进程地址页表的映射关系(如代码2)。 从运行结果我们可以看出,a的值不一样,证明两个a不是同一个变量(物理内存地址不一样)。我们打印的地址是一样的,实际上那是进程地址空间的地址,不是物理内存的地址。

// 代码2
#include<stdio.h>
#include<unistd.h>
int main()
{
    int a = 0;
    pid_t ret = fork();
    if (ret < 0)
    {
        perror("fork");
    }
    else if (ret)
    {
        a = 10;  // 这里父进程改变了a,发生了写时拷贝
        printf("parent[%d] --> a[%p] --> %d\n", getpid(), &a, a);
    }
    else
    {
        printf("child[%d] --> a[%p] --> %d\n", getpid(), &a, a);
    }
    return 0;
}

在这里插入图片描述

三. 进程地址空间的意义

  1. 对进程操作内存进行风险(权限)管理,起到保护物理内存以及各个进程数据的安全
  2. 有时候我们申请空间的时候不一定是马上就用,有了进程地址空间,可以将内存申请和内存使用在时间上划分清楚,这样可以减少内存空间的闲置
  3. 每一个进程都有自己独立的进程地址空间,以确保进程具有独立性。
    用在时间上划分清楚,这样可以减少内存空间的闲置
  4. 每一个进程都有自己独立的进程地址空间,以确保进程具有独立性
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

柿子__

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

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

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

打赏作者

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

抵扣说明:

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

余额充值