<1>. Linux多线程前置认识

  1. 再谈进程

进程:
1. 进程是进程相关的内核数据结构,加载自己的代码和数据的整体集合,而线程在进程内部执行,是操作系统调度的基本单位。
2. 理解进程是动态运行的.
3. 操作系统为进程创建相关的内核数据结构:进程的PCB,地址空间,页表。进程有对应的CPU寄存器存储进程的上下文数据。进程有与他相关的被打开的文件,信号。
4.只要操作系统要管理进程和与进程想要访问的资源,那么就要创建对应的数据结构来描述和管理,进程和某种资源的关系在操作系统看来就是数据结构之间的关系。
5. 进程的代码和数据通过用户级页表进行映射。
  1. 再谈堆区

栈区和代码区是被整体使用的,栈区有栈顶和栈底,我们很容易就能划分它的起始和结束。但是向堆上申请空间是零散化的。再Linux系统下,malloc底层调用的是brk,我们申请空间时,只告诉操作系统我们需要多少字节空间,但是并没有说什么时候结束?
在地址空间中,还有一种数据结构是vm_area_struct来对地址空间进行更加细粒度的划分,来指明堆区是属于谁的,哪块空间是第一次申请,哪块是第二次申请,(地址空间中的堆是标定堆区的起始和结束) 每个vm_area_struct通过链表链接,里面的start和end所表征的地址由操作系统帮你映射进物理内存。
  1. 再谈地址空间到物理内存的映射

1. 我们的可执行程序是按地址空间的方式划分的, 代码加载到内存之前,虚拟地址已经在二进制可执行程序,在磁盘上已经写好 编译器编译时将代码按4KB划分好,4KB就是操作系统内存管理的基本单位
4KB 称为页帧 ,物理内存按照4KB为单位划分为块, 称为页框 ,操作系统进行IO时以4KB为单位,将页帧装入页框,因为操作系统(按4kb为单位进行内存管理),编译器(在编译时将代码和数据按4kb为单位划分好)以4kb进行IO加载


2. 缺页中断 当OS在进行通过页表进行寻址时发现你要访问的数据不在内存中,我们需要:
1. 申请内存
2. 在磁盘中找到你要加载的目标数据
3. 把目标数据加载到你申请的内存位置
4. 重新填充页表(你刚刚申请的物理内存的地址)
5. 返回到用户
但这一切在用户看来时0感知的

3. 内存被划分为100w+个4kb,操作系统如何进行内存管理呢?一页为4kb,操作系统为了管理这些页创建了一种结构体struct page{ int flag(这个标志位用来表示页的使用情况/占用/非占用等)} 然后这些结构体可以用数组这样的数据结构组织起来,struct page mem[100w+],操作系统对内存的管理就是对这些特定数据结构的管理,内存的使用情况,内存合并,就通过修改page实现

3. 用户页表
用户页表+MMU集成在CPU上,CPU读到虚拟地址,出来的就是物理地址,若发现我需要缺页中断?就是在100w+个page中申请一个page,再根据页表位置,找到磁盘中的可执行程序,通过文件系统把内容加载到内存,再把4kb的内容对应的物理内存填到页表右侧

4. 以32位地址空间为例认识虚拟地址到物理地址的映射关系
虚拟地址2^32如果页表要维护2^32个映射关系,假设一条页表的条目为4byte的虚拟地址大小,4byte的物理地址大小,再加上一个是否缺页中断的标记为,那么至少是9byte,一共2^32组映射关系,难道光一张页表就要4GB*9byte吗,页表是一个软件,一种数据结构需要存储在内存中,这必然是不可能的,因此为了维护虚拟地址到物理地址,我们需要两张页表!!!

以32位 0000 0000 00 00 0000 0000 0000 0000 0000
构建一级页表 构建二级页表 页内偏移量
1. 一级页表和二级页表只需要维护从虚拟地址到物理内存的页的映射,一级页表必须有2^10个条目,但是二级页表可以只有几个
2. 一级页表左边是虚拟地址高10bit位,右边是和他匹配的二级页表,二级页表左边是虚拟地址次高10bit位, 右边为物理地址中对应页的起始地址,不是具体地址,是具体4kb的起始地址 ,虚拟地址的低12bit位是具体的页内偏移量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值