基本概念
- 原语:操作系统最底层+最接近硬件的部分+原子性
进程管理
进程 线程
多道程序下,允许多个程序并发执行,此时他们失去封闭性,并具有间断性以及不可再现性,所以引入进程的概念,以便更好地描述并发。
进程概念:
- 程序的一次执行过程
- 一个程序及其数据在处理机顺序执行时所发生的活动
- 是资源分配的基本单位
- 进程是动态的
- 运行
- 就绪:除了处理机以外的一切资源
- 阻塞:进程因为等待某个事情发生(除了处理器)而暂停
- 创建:正在被创建,尚未转到就绪态
- 结束:程序正常结束或者其他原因退出运行
线程概念
进程是为了更好的多道程序并发,线程是为了更好的减少并发执行付出的时空开销
- 是一个基本的CPU执行单元
- 是被独立调度的基本单位
- 与同属于一个进程的线程们共享所有资源
二者区别
- 调度:
- 线程是独立调度的基本单位
- 进程是拥有资源的基本单位
- 线程几乎不拥有自己的资源,可以访问进程的资源
- 并发性
- 线程之间可以并发,进程之间也可以并发,
- 系统开销
- 进程开销远远大于线程的,因为线程会有内存空间,IO设备等
- 线程切换只需要保存和设置极少的寄存器,开销小
- 又线程共享进程地址空间,因此线程之间通信与同步容易实现
- 地址空间
- 进程地址空间相互独立
- 线程共享进程的地址空间
- 通信
- 进程间通信需要使用进程同步和互斥等手段
- 线程可以直接设置读写数据段(比如全局变量)来通信
内核级线程
线程所有管理都是内核完成,应用程序没有线程管理的代码,只有一个内核级线程的编程接口
内核为每个线程维护上下文信息
JVM线程跟内核轻量级进程有一一对应的关系。
进程切换
- 保存处理机上下文,程序计数器+其他寄存器
- 更新程序控制块信息
- 把进程控制块放入相应的队列,例如阻塞或者就绪
- 选择另外一个进程执行
- 更新内存管理的数据结构
- 恢复处理机上下文
线程切换
进程的通信
- 共享存储:通信进程之间存在一块可直接访问的共享空间,通过这个共享空间执行读写操作实现信息交换
- 分为数据结构的共享+存储区的共享
- 消息传递
- 直接通信:发送消息给接收进程,并将它挂在接收进程的消息缓冲队列上,接收进程从消息缓冲队列取得消息
- 间接通讯:把消息发送给一个信箱,接收进程从信箱取得实体
- 管道通信:写进程向管道以字符流形式将大量的数据写入管道;接收进程从管道读数据
- 互斥、同步、确定对方存在
- 一次性操作,数据被读取,则从管道中抛弃
- 半双工,某一时刻单向通信
线程的通信
- volatile
- synchronized
- wait,join,notify
- Lock接口
- BlockingQueue
- ReentrantLock
- Semaphore
- PipedInputStream
- https://juejin.cn/post/6844903486895865864
进程线程切换的区别 https://blog.csdn.net/github_37382319/article/details/97273713
- 进程切换与线程切换的一个最主要区别就在于进程切换涉及到虚拟地址空间的切换而线程切换则不会。因为每个进程都有自己的虚拟地址空间,而线程是共享所在进程的虚拟地址空间的,因此同一个进程中的线程进行线程切换时不涉及虚拟地址空间的转换。
- 虚拟内存是操作系统为每个进程提供的一种抽象,每个进程都有属于自己的、私有的、地址连续的虚拟内存,当然我们知道最终进程的数据及代码必然要放到物理内存上,那么必须有某种机制能记住虚拟地址空间中的某个数据被放到了哪个物理内存地址上,这就是所谓的地址空间映射,也就是虚拟内存地址与物理内存地址的映射关系,那么操作系统是如何记住这种映射关系的呢,答案就是页表,页表中记录了虚拟内存地址到物理内存地址的映射关系。有了页表就可以将虚拟地址转换为物理内存地址了,这种机制就是虚拟内存。每个进程都有自己的虚拟地址空间,进程内的所有线程共享进程的虚拟地址空间。
- 为什么虚拟地址切换很慢?
- 现在我们已经知道了进程都有自己的虚拟地址空间,把虚拟地址转换为物理地址需要查找页表,页表查找是一个很慢的过程,因此通常使用Cache来缓存常用的地址映射,这样可以加速页表查找,这个cache就是TLB,Translation Lookaside Buffer,我们不需要关心这个名字只需要知道TLB本质上就是一个cache,是用来加速页表查找的。由于每个进程都有自己的虚拟地址空间,那么显然每个进程都有自己的页表,那么当进程切换后页表也要进行切换,页表切换后TLB就失效了,cache失效导致命中率降低,那么虚拟地址转换为物理地址就会变慢,表现出来的就是程序运行会变慢,而线程切换则不会导致TLB失效,因为线程线程无需切换地址空间,因此我们通常说线程切换要比较进程切换块,原因就在这里。
IO密集型+CPU密集型
CPU密集型适合进程,
处理机调度
先来先服务
短作业优先
优先级调度
高相应比优先 (等待时间+处理需要的时间)/(处理需要的时间)
时间片轮转
多级反馈队列
同步
- 临界资源:一次只能为一个进程所用
- 同步
- 直接制约关系
- 为了完成某种任务而建立的两个或多个进程
- 需要在某些位置协调他们工作次序而等待
- 互斥
- 间接制约
- 一个进程进入临界区以后,另一个进程必须等待
原则:
空闲让进
忙则等待
有限等待
让权等待:不能进入临界区,那么释放处理机
死锁
- 多个进程因为竞争而造成的一种僵局,如果没有外力作用,这些进程都无法向前推进
原因
- 互斥条件:一段时间内某个资源只能被一个进程所占有
- 不剥夺条件:进程的资源不能被剥夺,只能自己释放
- 请求并保持条件:已经保持了至少一个资源,但是又提出了新的请求,而这个资源已经被其他进程占有,被阻塞
- 循环等待条件:每个进程以获得的资源同时被链中下游一个进程所请求
解决
- 破坏互斥:不可行,有些资源不能让同时访问
- 破坏不剥夺条件:进程已经持有资源请求新的资源得不到满足的时候,必须释放已经保持的资源
- 破坏请求并保持:一次性申请完所有资源
- 破坏循环等待:按一个一致性的顺序申请资源
内存
虚拟内存
虚拟内存 的存在,通过 虚拟内存 可以让程序可以拥有超过系统物理内存大小的可用内存空间。另外,虚拟内存为每个进程提供了一个一致的、私有的地址空间,它让每个进程产生了一种自己在独享主存的错觉(每个进程拥有一片连续完整的内存空间)。这样会更加有效地管理内存并减少出错。
页表
逻辑地址(页号P,页内偏移量W)—->在页表寄存器中查询出页表的起始地址——> 根据页表起始地址,得出页号P对应的块号——>在物理地址中找到块号p,再加上w,就是物理地址
TLB
快表,相联存储器
如果页表都是在内存里面,那就需要访问一次页表得到物理地址,然后根据物理地址读取数据,两次访存。
快表可以记录若干的页表项,加速地址变换的过程。
虚拟内存
局部性
页面置换算法
先进先出
LRU算法
- 最近最久未使用Least Recently Used
时钟算法