现代操作系统笔记——第二章进程与线程
第二章进程与线程
进程
进程模型
进程就是一个正在执行程序的实例,包括程序计数器,寄存器和变量当前的值。
一个进程是某种类型的一个活动,它有程序、输入、输出以及状态。单个处理器可以被若干进程共享,使用某种调度算法决定何时停止一个进程的工作而为另一个进程服务。
进程创建
4种主要事件导致进程创建
1、系统初始化
2、正在运行的程序执行了创建进程的系统调用
3、用户请求创建一个新进程
4、一个批处理作业的初始化
创建进程之后,子进程和父进程有不同的地址空间,某个进程在其地址空间的修改对于另外一个进程不可见。
进程终止
通常由以下条件引起
正常退出(自愿的)
出错退出(自愿的)
严重错误(非自愿)
被其它进程杀死(非自愿)
进程的层次结构
进程有一个父进程,但是可以有多个子进程。
进程的状态
1、运行态(该时刻进程实际占用CPU)
2、阻塞态(可运行,但因为其它进程正在运行而暂时停止)
3、就绪态(除非某种外部事件发生,否则进程不能运行)
进程的实现
操作系统维护着一张进程表,每个进程占用一个表项,包括程序计数器,堆栈指针,内存分配情况,所打开的文件状态,账号,调度信息,以及其它进程由运行态转换到就绪态或阻塞态时必须保存的信息。
多道程序设计模型
采用多道程序设计有利于提高CPU的利用率
假设进程等待IO的时间与其停留在内存的时间之比为P,当内存中有n个进程时,所有进程等待IO概率为p^n,
则CPU利用率为: 1-p^n n为多道程序设计的道数。
线程
线程的使用
需要多线程原因:
1、在许多应用中同时发生着多种活动,某些活动随着时间推移会被阻塞,通过将其分解为可以准并行运行的多个顺序线程使程序设计模型更简单
2、线程比进程更加轻量级,比进程更容易创建和撤销。
3、若多个线程是CPU密集型,就不能获得性能上的增强,若存在大量计算和IO处理,多个线程允许这些活动彼此交叠进行,加快应用程序执行速度。
线程与进程的区别和联系
多线程共享同一地址空间,多进程共享物理内存。
每个线程的堆栈有一帧,供各个被调用但是还没有从中返回的过程使用,存放相应过程局部变量和调用完成后的返回地址。
用户空间线程
内核对线程包一无所知,按照单线程管理。每个进程有其专用线程表,记录各个线程的属性,如程序计数器、堆栈指针、寄存器、状态。
优点
- 可以在不支持线程的操作系统上实现。
- 同一进程内线程切换速度快,无需用户态内核态切换
- 允许每个进程有自己定制的调度算法
- 每个进程有自己的线程表
缺点
- 线程发起系统调用而阻塞时,整个进程需要等待。
- 缺页中断问题,如果有线程发送页面故障,会阻塞整个进程
- 如果一个进程开始运行,在该进程中的其它线程就不能运行,除非第一个线程自动放弃CPU。因为进程内部没有时钟中断,不能用轮转调度
内核空间线程
优点
缺点
需要从用户态切换到内核态
混合实现
进程间通信
竞争条件:两个或多个进程读写某些共享数据时,最后的结果取决于运行的精确时序。
临界区:共享内存进行访问的程序片段。
实现互斥方案
- 屏蔽中断。屏蔽中断就不会切换进程,但是若进程不再打开中断就终止系统。
- 锁变量。设置锁变量,进入临界区前测试锁,若为0就进入并设置为1。缺点是,如果读取锁变量为0后并且设置为1前,另一个进程改变锁变量,同样存在问题。
- 严格轮换。需要用到忙等待,非常浪费CPU。导致其他进程可能被阻塞。 连续测试一个值直到某个值出现,称为忙等待
- Peterson解法。
- TSL指令
生产者消费者问题
生产者判断缓冲区是否满,满了就睡眠并唤醒消费者,消费者判断缓冲区是否为0.
存在的问题:
信号量
使用一个整形变量来累计唤醒次数。设立两种操作:down和up。
Down操作:检查值是否大于0,大于0就减一并继续,若为0就睡眠,然后检查数值等
Up操作:对信号量的值加一
需要确保同一时刻只有一个CPU对信号量进行操作。
快速用户区互斥量futex
管程
一个由过程、变量及数据结构组成的集合。进程在需要的时候调用管程中的任何过程。任何时候管程中只能有一个活跃进程。
管程可以保证:如果生产者发现缓冲区已满,它能完成wait操作而不用担心调度程序会在wait完成之前切换到消费者。
Pascal的管程实现
调度
何时调度
- 创建一个新进程,需要决定运行父进程还是子进程
- 一个进程退出
- 进程阻塞在IO或信号量或由于其它原因
- IO中断发送时
非抢占式调度:进程运行到被阻塞或自动放弃CPU,不会被强迫挂起。
抢占式调度:让进程运行某个固定时段的最大值,如果时段结束时,进程还在运行就挂起它,选择另一个就绪的进程运行。
调度算法分类
- 批处理
- 交互式
- 实时
调度算法目标
批处理系统中的调度
- 先来先服务FIFS
进程按照请求CPU的顺序使用CPU,运行期望的时间长度就排到就绪队列尾部,正在运行的进程被阻塞时,就绪队列的第一个进程开始运行。
优点:易于理解和实现
缺点:不利于IO密集型进程
- 最短作业优先
从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行。
- 最短剩余时间优先
选择运行剩余时间最短的进程运行,运行时间必须提前掌握
交互式系统中的调度
- 轮转调度
每个进程被分配一个时间段,允许进程在该时间段内运行,时间片结束时还在运行就剥夺CPU给另一个进程吗,如果在时间片结束之前阻塞或结束就立即切换CPU。调度程序维护可运行程序列表。
特点:时间片太短会导致过多的进程切换,降低CPU效率;太长会导致对短的交互请求响应时间变长。
- 优先级调度
每个进程被赋予一个优先级,允许优先级最高的可运行进程先运行。
- 多级队列
- 最短进程优先
最短作业伴随着最短响应时间
- 保证调度
- **调度
给重要的进程额外的**。
反应迅速
- 公平分享调度
实时操作系统中的调度
硬实时调度:在绝对截止时间前完成,软实时调度:在某个时间前后完成调度
调度策略与机制分离:将调度算法以某种形式参数化,具体参数由用户进程写入。调度机制位于内核,调度策略可由用户进程决定。
线程调度
用户线程可以使用专为应用程序定制的线程调度程序。
哲学家就餐(IPC)问题
可能同时拿到左叉,然后发现右叉不可用,同时放下,循环往复。
解决方法:
1、拿不到右叉时等待随机的一段时间
2、互斥量