基本概念
临界资源:
一次只允许一个进程使用的资源
临界资源的访问过程
进入区:检查进程是否可以进入临界区
临界区:可以访问临界资源的代码
退出区:将正在访问临界区的标志清除
剩余区:代码中剩余部分
同步
直接制约关系:为了完成某种任务而建立的多个进程,相互合作,所以要进行通信同步
遵循的原则
1)空闲让进:临界区空闲时间,允许一个请求进入临界区的进程立即进入临界区
2)忙则等待:已有进程进入临界区后,其他试图进入临界区的进程必须等待
3)有限等待:对于请求进入访问临界区的进程,在有时间内进入临界区
4)让权等待:进程不能进入临界区的时候,应该立即释放处理机
互斥:
间接制约关系,当一个进程访问临界资源的时候,其他进程不能访问
实现临界区互斥的方法
软件实现方法
1.单标志法:
两个进程交替进入临界区
优点:实现简单
缺点:两个进程可能同时进入临界区,违背忙则等待
2.双标志先检查:
每个进程在访问临界区资源前,先检查临界资源是否被访问,如果空闲才能进入;
优点:不用交替进入可以连续使用
缺点:两个进程可能同时进入临界区,违背忙则等待
3.双标志后检查:
先设置自己的标志,表示自己想进入,检查对方标志,如果对方也要进入,那么就等待,否则就进入.
优点:不会导致两个进程同时进入临界区
缺点:双方可能会互相谦让,导致饥饿现象
4.皮特森算法:
防止两个进程无线等待,在双标志后检查法的基础上增加了一个标志位,从而防止饥饿。
优点:解决了饥饿问题
缺点:算法复杂
硬件实现方法
1.中断屏蔽法:
对终端进行屏蔽、关中断
优点:关中断非常方便
缺点:限制了处理机交替执行程序的能力
2.硬件指令法
读出指定标志后,将该标志置为真
优缺点:
优点:
1.适用于任意数目的进程
2.简单且容易验证正确性
3.支持进程内有多个临界区
缺点
1.不能实现让权等待
2.可能会导致饥饿现象
信号量
整形信号量
wait:资源-1 ;signal = 资源+1
wait(S)
while(S <= 0);
S = S-1;
Signal(S)
S= S +1
没有遵循让权等待机智,会导致进程处于“忙等”状态
记录型信号量
typedef struct{
int value;
struct process *L; //阻塞队列
}semaphore;
void wait(semaphore S){
S.value --;
if(S.value <0){
add this process ti S.L; //将进程添加到对应的阻塞队列中
block(S.L) //阻塞该进程
}
}
void signal(semaphore S){
S.value++;
if(S.value <= 0){
remove a process P form S.L; //从阻塞队列对头选取一个进程
wakeup(P); //唤醒该进程
}
}
记录型信号量不存在“忙等”现象
管程
定义:
一组数据以及定义在这组数据之上的对这组数据的操作组成的软件模块,这组操作能初始化并改变管程中的数据并同步进程
组成:
1.局部于管程的共享结构的数据说明
2.对该数据结构进行操作的一组过程
3.对局部于管程的共享数据设置初始值的语句
管程类似于c++中的类结构,1.局部于管程的数据结构 是私有变量 ,2.对数据结构操作的一组过程是类内的函数,3.初始化语句是类内对私有变量进行初始化的语句
基本特性:
1.局部于管程的数据只能被局部与管程内的过程所访问
2.一个进程只能通过调用管程内的过程才能进入管程访问共享数据
3.每次仅允许一个进程在管城内执行某个过程