1.冯诺依曼体系结构
2.操作系统OS-operator system
3.进程概念
4.进程创建
5.进程状态
6.环境变量
7.程序地址空间
1.冯诺依曼体系结构-现代计算机的硬件体系结构
输入设备
输出设备
存储器
运算器
控制器
运算器和控制器-CPU-中央处理器
存储器-内存-所有设备都是围绕内存工作-cpu要处理任何数据都需要先将数据加载到内存中-内存是中间的数据缓冲带-内存的存储介质是一种易失性介质-断电后数据丢失-内存比硬盘吞吐量快
2.操作系统
内核+应用
内核-进程管理,内存管理,文件管理,驱动管理-管理计算机上的软硬件资源
应用-函数库,shell-使计算机更加好用
如何管理?
先描述再组织
描述-struct结构体
组织-链表等数据结构
对下管理硬件资源,对上提供良好的应用执行环境
#用户-指令操作,开发操作,管理操作
#用户操作接口-lib函数库,shell
#系统调用接口system call
#操作系统-进程管理,内存管理,文件管理,驱动管理
#驱动程序
#底层硬件
库函数和系统调用接口的关系-库函数封装了系统调用接口
3.进程概念
进程-进程就是一个pcb-pcb是操作系统对一个程序运行的描述,通过这个描述实现对程序运行的调度管理-在linux下就是一个task_struct结构体
程序-一系列有序的指令集合
pcb-进程控制块-描述进程-存放进程信息-进程属性的集合-Linux下pcb就是一个task_struct结构体
task-struct:
#进程标识符pid
#进程状态
#进程优先级
#内存指针-指向程序指令数据在内存中的位置
#程序计数器-保存当前程序的运行
#上下文数据-保存当前程序的运行
#IO信息
#记账信息
操作系统如何实现多个程序的调度运行?
先描述再组织
通过pcb的调度管理实现对程序的切换调度运行
cpu分时机制-实现多任务的并发/并行处理-cpu以极快的速度切换调度运行所有程序,造成大家都在运行的假象-操作系统调度一个进程在cpu上运行,只运行很短的一段时间-时间片运行完毕-则切换调度到下一个程序
cpu多核-多个处理核心-每个核心都有自己的寄存器-可以调度一个程序的运行
并发-轮询执行
并行-同时执行
4.进程创建
进程就是pcb-创建一个进程-创建了一个pcb
pid_t fork(void)-通过复制调用进程(父进程)-创建一个新的进程(子进程)-创建了一个新的pcb然后从父进程pcb中复制了很多数据到新的pcb-内存指针,程序计数器,上下文数据
内存指针-父子进程运行的代码一样-指向同一块物理内存中的数据及指令
程序计数器上下文数据-子进程被创建出来后-运行位置与父进程一样
为什么创建子进程?
子进程干的事和父进程一样-分摊父进程工作-提高效率
父子进程代码共享,数据独有
fork函数父子进程返回值不同
父进程返回子进程pid
子进程返回0
错误返回-1
根据fork返回值进行代码分流-让父子进程进入不同的判断执行体-完成不同的功能
pid_t getpid(void)-返回调用进程的pid-谁调用就返回谁的pid
5.进程状态
运行/就绪/阻塞
Linux下-RSTDZ
R-运行状态-运行/就绪
S-可中断休眠态-当前的阻塞能够被中断唤醒
T-停止态-停止运行,什么也不干
D-不可中断休眠态-当前的阻塞不会被中断唤醒-等待条件满足后自动唤醒
Z-僵死态-进程已经退出但资源没有完全被释放-一种等待后续处理的状态
进程状态查看指令
ps -ef
ps -efl
ps -aux
ps -aux|grep 进程名 -过滤
!ps -使用最近一次使用的ps命令
kill -杀死一个进程
kill -9-强制杀死一个进程
僵尸进程-处于僵死状态的进程-进程已经退出,但资源没有完全释放(子进程要保存退出原因)
产生-子进程先于父进程退出-但是父进程没有进行进程等待-导致无法获取子进程的退出状态-因此操作系统无法直接释放子进程资源-子进程成为僵尸进程
危害-1.内存泄漏-资源没有完全回收会占用内存资源
-2.占用进程资源-一个用户能创建的进程数量是有限的-ulimit -a查看最多能创建的进程
处理-进程等待-等待子进程的退出
-退出父进程
避免?
孤儿进程-一种运行在后台-父进程是1号进程(init)的进程
产生--父进程先于子进程退出-子进程成为孤儿进程
守护进程(精灵进程)-一种特殊的孤儿进程-父进程是1号进程,运行在后台的批处理程序-与终端和登录会话脱离关系
进程优先级-一个进程对cpu资源获取的优先权
为什么有进程优先级?-让操作系统运行的更加合理
交互式进程
批处理进程
6.环境变量-配置系统运行环境参数的变量-让系统环境配置更加灵活(不用再去修改配置文件,重新加载配置文件,而是直接设置直接生效)
命令操作
env/set(查看所有变量,包含环境变量)/echo -查看环境变量
export -设置环境变量
unset -删除环境变量
代码操作
mian函数的第三个参数
int main(int argc,char*argc[],char*env[])
-env保存环境变量
全局变量extern char**environ -environ保存环境变量
char*getenv(const char*name)-通过环境变量名称获取一个指定环境变量的数据
环境变量具有继承特性-子进程也拥有父进程的环境变量
7.程序地址空间-进程的虚拟地址空间
C/C++内存管理
32位操作系统
高地址0xffffffff
-内核空间1G
-用户空间3G
环境变量/运行参数
栈
↓
共享区
↑
堆
未初始化全局变量
初始化全局变量
代码段
低地址0x00000000
程序不占用内存,存放在硬盘上,运行起来的程序被加载到内存,才会占用内存
进程访问的地址都是虚拟地址,程序地址空间实际上是进程的虚拟地址空间
虚拟地址空间-操作系统通过mm_struct向进程描述出一个虚拟的线性的地址空间(空有地址编号,不具备存储功能)
为什么描述一个虚拟地址空间-不让进程直接访问物理内存
进程直接访问物理内存
-1.进程中代码数据使用的是连续的地址,直接使用连续的物理内存会造成内存的浪费
-2.缺乏内存访问控制-导致进程不安全
进程通过虚拟地址访问物理内存
操作系统通过一个mm_struct结构体为进程创建一个虚拟地址的同时,也创建了一个页表-用于映射虚拟地址与物理地址的关系
进程使用虚拟地址空间-通过页表映射物理内存-实现进程中数据在物理内存上的离散式存储-提高了内存利用率
在页表中可以针对某个地址设置访问权限-实现内存访问控制
页表功能
-1.映射虚拟地址和物理地址的关系-提高内存利用率
-2.提供内存访问控制
每个进程都有一个虚拟地址空间和一个页表-提高进程独立性
页表如何通过虚拟地址访问物理地址-MMU
内存管理方式
-1.分页式内存管理
-2.分段式内存管理
-3.段页式内存管理
分页式内存管理的虚拟地址组成:页号+页内偏移
页号-页表中页表项编号
页内偏移-一个变量首地址相较于内存页起始位置的偏移量
物理地址=物理内存块号*物理内存块大小+虚拟地址中的页内偏移
分页式内存管理-对物理内存进行分块管理-通过页表映射实现数据在物理内存上的离散式存储-提高内存利用率
分段式内存管理
地址组成=段号+段内偏移
段表
段号-物理段起始地址
分段式内存管理-使程序员对内存管理更加方便-将内存空间分为代码段...什么变量就在什么段申请地址
段页式内存管理-先分段-在每个段内分页(在每一个分段内采用分页式管理)
地址组成=段号+段内页号+页内偏移+段表+段内页表
分页式-提高内存利用率
分段式-便于程序员/编译器内存管理
段页式-集合了分页式和分段式优点
缺页中断
磁盘分区-文件系统分区和交换分区
每个进程的页表中记录了每一个虚拟地址对应的物理地址-如果某个虚拟页面的物理内存中的数据被交换出去了,保存到交换分区,则将这个页表项置为缺页中断
等待下次这个进程要访问这个被交换出去的数据的时候,触发缺页中断,重新从交换分区中交换回来
什么样的数据在内存不够用时被交换出去?
LRU算法-最久未使用