完成操作系统第二章进程与线程
parent
ecf76d91fc
commit
31a9843c20
|
@ -6,6 +6,29 @@ date: 2023-07-01T15:59:00+08:00
|
|||
|
||||
## 线程
|
||||
|
||||
### 难点和常考点
|
||||
|
||||
* 进程与程序的区别和联系
|
||||
* 进程是动态的,程序是静态的
|
||||
* 进程 = 程序+数据+PCB
|
||||
* 程序 = 一组有序的指令集合
|
||||
* 进程是动态创建消失的,程序是永久存在的,可长期保存
|
||||
* 进程= 程序的一次执行过程
|
||||
* 程序 = 一组代码的集合
|
||||
* 进程可以执行一个或几个程序,程序也可以构成多个进程
|
||||
* 进程可以创建进程,程序不可以创建程序
|
||||
* 死锁与饥饿
|
||||
* 定义
|
||||
* 死锁 = 两个或多个进程无限地等待一个事件,而该事件只能由这些等待进程之一来产生
|
||||
* 饥饿/无限期阻塞 = 进程在信号量内无穷等待的情况
|
||||
* 差别
|
||||
* 饥饿并不代表系统一定会死锁,但至少有一个进程的执行被无限期推迟
|
||||
* 进入饥饿的状态进程可以只有一个,但进入死锁状态的进程鼻血大于等于2个
|
||||
* 处于饥饿状态的基础可以是一个就绪进程,但是死锁状态的进程必定时阻塞进程
|
||||
* 同步与互斥的区别和联系
|
||||
* 同步:进程之间竞争使用临界资源,只能让他们逐个使用
|
||||
* 互斥:进程之间协同完成任务,在关键点上等待另一个进程发来的消息,以便协同一致
|
||||
|
||||
### 常考知识点
|
||||
|
||||
* 交换数据
|
||||
|
@ -23,7 +46,7 @@ date: 2023-07-01T15:59:00+08:00
|
|||
* 进程与进程的关系
|
||||
* 进程与进程之间完全隔离,线程与线程之间没有隔离
|
||||
* 一个进程的状态变化可能引起另一个进程的状态变化
|
||||
* 如大衣呢进程结束后可能改变另一个等待打印机的进程
|
||||
* 如打印机进程结束后可能改变另一个等待打印机的进程
|
||||
* 各种状态
|
||||
* 死锁的进程位于阻塞态,不可能所有进程都处于就绪态,但可以所有的进程都处于阻塞态(死锁的时候)
|
||||
* 就绪队列进程的多少与处理器的效率无关,只有当就绪队列为空时,CPU进入等待态,CPU效率下降
|
||||
|
@ -685,4 +708,259 @@ P2(){
|
|||
|
||||
```
|
||||
|
||||
### 经典同步问题
|
||||
|
||||
#### 生产者-消费者问题
|
||||
|
||||
* 问题描述
|
||||
* 系统中有一组生产者进程和一组消费者进程
|
||||
* 生产者进程每次生产一个产品放入缓冲区
|
||||
* 消费者进程每次从缓冲区中取出一个产品并使用
|
||||
* 任何时刻,只能有一个生产者或消费者可以访问缓冲区
|
||||
|
||||
* 同步与互斥关系和设置的信号量
|
||||
* 题目的同步互斥关系
|
||||
* 缓冲区:生产者、消费者共享一个初始为空,大小为n的缓冲区
|
||||
* 同步关系1:只有缓冲区没满时,(优先级高),生产者才能把产品放入缓冲区(优先级低),否则必须等待
|
||||
* 同步关系2:只有缓冲区不空时(优先级高),消费者才能从中取出产品(优先级低),否则必须等待
|
||||
* 互斥关系:缓冲区是临界资源,各进程必须互斥地访问
|
||||
* 设置的信号量
|
||||
* empty
|
||||
* 同步信号量(对应同步关系1)
|
||||
* 表示生产者还能生成多少,即还能放入缓冲区多少产品
|
||||
* 该数量小于等于0,则生产者不能生产
|
||||
* 初始化为n
|
||||
* full
|
||||
* 同步信号量(对应同步关系2)
|
||||
* 表示消费者还能从缓冲区取出多少,即当前缓冲区已有产品的数量
|
||||
* 该数量小于等于0,则消费者不能进行读取
|
||||
* 初始化为0
|
||||
* mutex
|
||||
* 互斥信号量
|
||||
* 实现对缓冲区的互斥访问
|
||||
* 初始化为1
|
||||
* 代码
|
||||
|
||||
```C
|
||||
|
||||
semaphore empty = n;//同步信号量
|
||||
semaphore full = 0;//同步信号量
|
||||
semaphore mutex = 1;//互斥信号量
|
||||
|
||||
//生产者
|
||||
|
||||
producer(){
|
||||
while(1){
|
||||
P(empty);//申请一个生产者可用数量
|
||||
p(mutex);//互斥使用缓冲区
|
||||
把产品放入缓冲区
|
||||
V(mutex);//释放缓冲区占用
|
||||
V(full);//增加一个消费者可用数量
|
||||
}
|
||||
}
|
||||
|
||||
//消费者
|
||||
consumer(){
|
||||
P(full);//申请一个消费者可用数量,若该信号量小于等于0,则阻塞,不进行消费
|
||||
p(mutex);//互斥使用缓冲区
|
||||
从缓冲区中取出一个产品
|
||||
V(mutex);//释放缓冲区占用
|
||||
V(mutex);//增加一个缓冲区/生产则可用数量
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
#### 读者-写者问题
|
||||
|
||||
* 问题描述
|
||||
* 一些进程只读数据,称“读者”
|
||||
* 另一些会对数据进行修改,称“写者”
|
||||
* 写者与写者互斥,写者与读者互斥
|
||||
* 读者之间不互斥
|
||||
* 同步互斥关系与信号量
|
||||
* 写进程
|
||||
* 互斥访问,保证写者和读者互斥,写者和写者互斥
|
||||
* 读进程
|
||||
* 若为第一个读者,实现与写者的互斥,若为后继读者,则不需要
|
||||
* 若为最后一个读者,需要考虑唤醒阻塞的写者,以便能够让写者有机会进入临界区
|
||||
* 设置信号量
|
||||
* writemutex:控制写者互斥的访问共享数据,初值为1;
|
||||
* readCount:读者计数器,记录当前读者数,初值为0;
|
||||
* readmutex:控制读者互斥访问readcount,初值为1;
|
||||
* 代码
|
||||
|
||||
|
||||
```C
|
||||
|
||||
//写进程
|
||||
do{
|
||||
wait(writemutex);
|
||||
//写者完成编写
|
||||
signal(writemutex);
|
||||
}while(true);
|
||||
|
||||
//读进程
|
||||
|
||||
do{
|
||||
wait(readmutex);
|
||||
readcount ++;
|
||||
if(readcount == 1)
|
||||
wait(writemutex);
|
||||
signal(readmutex)
|
||||
|
||||
//执行读
|
||||
|
||||
wait(readmutex);
|
||||
readcount --;
|
||||
if(readcount ==0)
|
||||
signal(writemutex);
|
||||
signal(readmutex);
|
||||
|
||||
}while(true);
|
||||
|
||||
```
|
||||
|
||||
#### 哲学家进餐问题
|
||||
|
||||
* 问题描述
|
||||
* 5个哲学家围绕一张圆桌而坐,桌上放着5根筷子,哲学家进餐时需要同时拿起左边和右边的筷子
|
||||
* 思路一
|
||||
* 对于每一个哲学家,先等待左边的筷子可用,然后等待右边的筷子可用
|
||||
* 吃饭
|
||||
* 放下两根筷子
|
||||
* 问题
|
||||
* 极端情况下,5个哲学家同时拿起左边的筷子,势必会造成每个人都只有左筷子而没有右筷子,造成死锁现象
|
||||
* 解决方法
|
||||
* 同时最多允许四个哲学家围坐在桌子周围
|
||||
* 只有哲学家两侧的筷子都可用时才允许他捡起筷子
|
||||
* 代码
|
||||
|
||||
```c
|
||||
|
||||
do{
|
||||
Swait(chopstick[(i+1)%5],chopstick[i]);
|
||||
//eat
|
||||
Ssignal(chopstick[(i+1)%5,chopstick[i]]);
|
||||
//think
|
||||
}while(true);
|
||||
|
||||
|
||||
```
|
||||
|
||||
## 死锁
|
||||
|
||||
### 常考点
|
||||
|
||||
* 每个进程都分得一个资源,而且还有多余的资源可让任意一个进程使用,则不出现死锁
|
||||
* 多道程序技术要求进程间能够实现并发,需要实现进程调度保证CPU的工作效率,而并发性的实现需要中断功能的支持
|
||||
* 系统资源不足不是系统产生死锁的原因,资源不足只会对进程造成饥饿
|
||||
* 设进程有X个,每个进程最多请求使用3个A资源,系统有11个A资源,则不会出现死锁的最大X为
|
||||
* 2*X + 1 =11,解得X = 5(极端情况时,每个进程分配2个A资源,只要有一个资源就不会出现死锁)
|
||||
|
||||
|
||||
### 死锁概念
|
||||
|
||||
* 死锁是多个进程因为竞争资源而造成的一种互相等待
|
||||
* 死锁的充分条件:资源分配图中每个资源只有一个,又出现了环路
|
||||
|
||||
### 死锁产生原因
|
||||
|
||||
* 系统资源的竞争【空间上】
|
||||
* 系统中不可剥夺资源不足以满足多个进程
|
||||
* 只有对不可剥夺资源的竞争才可能产生死锁
|
||||
* 进程推进顺序非法【时间上】
|
||||
* 进程运行时,请求和释放资源的顺序不当
|
||||
* 系统对独占资源分配不当
|
||||
|
||||
### 产生死锁的必要条件
|
||||
|
||||
* 需要同时满足以下四个条件
|
||||
* 互斥条件:多个线程不能同时使用同一个资源
|
||||
* 不剥夺条件:进程A已经拥有资源1,在自己使用完之前不能被其他进程获取
|
||||
* 请求并保持条件:进程A已经有资源1,想申请资源2,但是资源2被进程B持有,进程A处于等待状态,但是进程A不释放资源1
|
||||
* 循环等待条件:两个线程获取资源的顺序构成了环形链
|
||||
|
||||
|
||||
### 如何解决死锁
|
||||
|
||||
* 死锁预防
|
||||
* 破坏互斥条件
|
||||
* 缺点:打印机等临界资源只能互斥使用
|
||||
* 举例
|
||||
* 方法不可行
|
||||
* 破坏不剥夺条件
|
||||
* 常用于状态易于保存和恢复的资源(CPU的寄存器和内存资源)
|
||||
* 举例
|
||||
* 剥夺资源法
|
||||
* 破坏请求并保持条件
|
||||
* 可能会导致饥饿现象
|
||||
* 举例
|
||||
* 一次性分配策略
|
||||
* 破坏循环等待条件
|
||||
* 可采用顺序资源分配法,但是编号必须相对稳定,限制了新类型设备的增加
|
||||
* 举例
|
||||
* 资源有序分配策略
|
||||
* 死锁避免
|
||||
* 安全性算法
|
||||
* 银行家算法
|
||||
* 死锁包含在不安全状态之中【系统处于安全状态时,一定无死锁;系统处于不安全状态时,不一定出现死锁】
|
||||
* 死锁避免时不会限制用户申请资源的顺序,需要进程运行所需资源的总量信息,不会给可能导致死锁的进程分配资源
|
||||
* 死锁检测
|
||||
* 资源分配图
|
||||
* 资源分配图是一个有向图,用于表示某时刻系统资源与进程之间的状态
|
||||
* 圆圈表示进程,框表示一类资源,从进程到资源的边叫做请求边,从资源到进程的边叫做分配边
|
||||
* 死锁定理
|
||||
* S为死锁的条件是当且仅当S状态的资源分配图是不可完全简化的
|
||||
* 死锁解除
|
||||
* 资源剥夺法
|
||||
* 资源剥夺法:挂起某些死锁进程,并抢占它的资源
|
||||
* 撤销进程法:强制撤销部分甚至全部死锁进程并剥夺这些进程的资源
|
||||
* 进程回退法:让一个或多个进程回退到足以回避死锁的地步
|
||||
* 各策略比较
|
||||
* 死锁预防
|
||||
* 资源分配策略
|
||||
* 保守,宁可资源闲置
|
||||
* 各种可能模式
|
||||
* 一次请求所有资源,资源剥夺,资源按序分配
|
||||
* 主要优点
|
||||
* 适用于突发式处理的进程,不必进行剥夺
|
||||
* 主要缺点
|
||||
* 效率低,进程初始化时间延长,剥夺次数过多,不便灵活申请新资源
|
||||
* 死锁避免
|
||||
* 资源分配策略
|
||||
* 是预防和检测的折中(运行时判断是否可能死锁)
|
||||
* 各种可能模式
|
||||
* 寻找可能得安全允许顺序
|
||||
* 主要优点
|
||||
* 不必进行剥夺
|
||||
* 主要缺点
|
||||
* 必须知道将来的资源需求,进程不能被长时间阻塞
|
||||
* 死锁检测
|
||||
* 资源分配策略
|
||||
* 宽松,只要允许就分配资源
|
||||
* 各种可能模式
|
||||
* 定期检查死锁是否已经发生
|
||||
* 主要优点
|
||||
* 不延长进程初始化时间,允许对死锁进行现场处理
|
||||
* 主要缺点
|
||||
* 通过剥夺解除死锁,造成损失
|
||||
|
||||
#### 安全性算法和银行家算法例题举例
|
||||
|
||||

|
||||
|
||||
安全性算法解法
|
||||
|
||||

|
||||
|
||||
|
||||
银行家算法解法
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 374 KiB |
Binary file not shown.
After Width: | Height: | Size: 643 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.0 MiB |
Loading…
Reference in New Issue