Linux中进程概念相关, 进程地址空间

在了解进程地址空间之间, 我们先来看一段代码

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

int gval = 1;//全局变量
int main()
{
    pid_t pid = 0;

    pid = fork();
    if (pid == 0) {
        //子进程会进入这个判断
        gval=100;//在子进程当中修改这个全局变量的值
        printf("child gval:%d---%p\n", gval, &gval);//打印这个全局变量的值和地址
    }else if (pid > 0) {
        //父进程会进入这个判断
        sleep(3);
        //子进程修改之后再让父进程打印,看看数据
        printf("parent gval:%d---%p\n", gval, &gval);
    }
    return 0;
}

//打印结果
child gval:100---0x80497e8
parent gval:1---0x80497e8

打印的结果会出现一个奇怪的现象, 子进程修改了全局变量gval的值, 打印出来与父进程的值不同, 这个我们知道是用到了写实拷贝技术, 但是打印出来的地址竟然是一样的!
在我们已知的概念当中, 数据不同, 表示肯定没有使用同一块内存空间, 也就是说在同一块内存空间党总不可能存储两个数据, 但这里父进程与子进程打印出来的数据不同, 但是地址是相同的, 那这不是矛盾了吗?

这其实就引出了我们接下来要学习的内容—进程地址空间.
实际上, 进程所访问的地址都是虚拟地址, 而我们通常所说的程序地址空间实际上是一个进程的虚拟地址空间.

那虚拟地址空间到底是什么意思呢? 它又是怎样虚拟出来的呢? 为什么要虚拟这样一片地址空间?

首先, 虚拟地址空间在Linux下其实就是一个mm_struct结构体, 通过这个结构体向进程描述出了一个完整的, 连续的内存空间
在这个结构体当中有许多信息, 其中较为重要的有
size: 表示所虚拟处的内存空间的大小
code_start: 描述代码段的起始位置
code_end: 描述代码段的结束位置

通过这些信息就可以描述出一块内存空间, 告诉进程这块空间可以随便使用.

那为什么要描述这样一个虚拟地址空间呢?
其实就是为了实现不让进程直接去访问物理内存, 我们假设下面这样一个场景.
假如进程可以直接访问物理内存空间

在这里插入图片描述
现在又有一个进程需要5M的物理内存, 那么我们应该怎么办?

假如干掉上面占用4M物理内存的进程, 那么我们原本16M的物理内存现在剩余8M, 8M>5M, 理论上我们可以加载这个5M的新进程了, 但是, 我们需要的是一片连续的内存空间, 也就是说, 现在我们依然无法使用剩余的8M内存空间, 这其实就是我们想说明的问题, 那就是如果进程直接去使用连续的物理内存, 那么很有可能造成很大的内存浪费, 正如我们上面的例子, 明明有8M剩余, 我只需要5M, 你还是不让我用!
除此之外, 直接访问物理内存, 缺乏内存访问控制, 导致进程不安全.(意思就是, 占用4M物理内存的进程用一个指针指向占用8M内存进程的空间, 这样很容易出问题).
因此, 我们需要描述这样一块虚拟地址空间

虽然有了这样一块虚拟地址空间, 但我们进程对应的数据和代码还是要存在物理空间上的, 那如何才能通过虚拟地址去访问物理内存呢?
实际上, 操作系统在为进程创建mm_struct结构体(虚拟地址空间)的时候, 还创建了一个页表, 用于映射虚拟地址空间与物理内存的的关系, 进程使用虚拟地址空间, 通过页表映射物理内存, 以此实现进程对应数据在物理内存上的离散式存储, 同时提高内存的利用率.
在页表中还可以直接针对某个地址设置访问权限, 进而实现内存访问控制.

总结

  1. 虚拟地址空间是什么?
    在Linux下虚拟地址空间实际上就是一个mm_struct结构体, 操作系统通过这个结构体为进程描述出了一块完整的连续的地址空间, 让进程可以随意使用.
  2. 为什么要使用虚拟地址空间?
    1. 使用虚拟地址空间, 通过页表映射物理内存, 可以实现数据的离散式存储, 提高内存利用率
    2. 通过页表实现内存访问控制.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值