diff --git a/content/408/《操作系统》进程与线程.md b/content/408/《操作系统》进程与线程.md index e50656b..5027a31 100644 --- a/content/408/《操作系统》进程与线程.md +++ b/content/408/《操作系统》进程与线程.md @@ -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状态的资源分配图是不可完全简化的 +* 死锁解除 + * 资源剥夺法 + * 资源剥夺法:挂起某些死锁进程,并抢占它的资源 + * 撤销进程法:强制撤销部分甚至全部死锁进程并剥夺这些进程的资源 + * 进程回退法:让一个或多个进程回退到足以回避死锁的地步 +* 各策略比较 + * 死锁预防 + * 资源分配策略 + * 保守,宁可资源闲置 + * 各种可能模式 + * 一次请求所有资源,资源剥夺,资源按序分配 + * 主要优点 + * 适用于突发式处理的进程,不必进行剥夺 + * 主要缺点 + * 效率低,进程初始化时间延长,剥夺次数过多,不便灵活申请新资源 + * 死锁避免 + * 资源分配策略 + * 是预防和检测的折中(运行时判断是否可能死锁) + * 各种可能模式 + * 寻找可能得安全允许顺序 + * 主要优点 + * 不必进行剥夺 + * 主要缺点 + * 必须知道将来的资源需求,进程不能被长时间阻塞 + * 死锁检测 + * 资源分配策略 + * 宽松,只要允许就分配资源 + * 各种可能模式 + * 定期检查死锁是否已经发生 + * 主要优点 + * 不延长进程初始化时间,允许对死锁进行现场处理 + * 主要缺点 + * 通过剥夺解除死锁,造成损失 + +#### 安全性算法和银行家算法例题举例 + +![](../../images/安全性算法和银行家算法举例.jpg) + +安全性算法解法 + +![](../../images/安全性算法和银行家算法举例安全性算法解法.jpg) + + +银行家算法解法 + +![](../../images/安全性算法和银行家算法举例银行家算法解法.jpg) + + + + + diff --git a/static/images/安全性算法和银行家算法举例.jpg b/static/images/安全性算法和银行家算法举例.jpg new file mode 100644 index 0000000..8ceb492 Binary files /dev/null and b/static/images/安全性算法和银行家算法举例.jpg differ diff --git a/static/images/安全性算法和银行家算法举例安全性算法解法.jpg b/static/images/安全性算法和银行家算法举例安全性算法解法.jpg new file mode 100644 index 0000000..774044a Binary files /dev/null and b/static/images/安全性算法和银行家算法举例安全性算法解法.jpg differ diff --git a/static/images/安全性算法和银行家算法举例银行家算法解法.jpg b/static/images/安全性算法和银行家算法举例银行家算法解法.jpg new file mode 100644 index 0000000..80d1726 Binary files /dev/null and b/static/images/安全性算法和银行家算法举例银行家算法解法.jpg differ