多个进程共享一种资源,但是该资源一次仅运行一个进程使用,当某一个进程在使用时,其他进程必须等待。
由任务协作引起,若干个进程为了完成一项任务必须有一定的先后执行顺序。例如A->B->C,只有当进程执行结束以后B进程才可以执行。
若干个进程为了完成一个共同的任务而相互合作,由于各个进程的推进速度不一样,为了协调,需要等待其他进程发送消息。进程之间这种相互合作等待对方消息的协调关系就称为进程同步。
进程之间争夺互斥资源引起的。
一段时间内只允许一个进程使用得资源
进程中访问临界资源的代码段称为临界区
类比:临界区就像是一个一次只允许一条船进入的闸门,进程就像船只
进入区------->临界区------->退出区
船在进入区获得临界区的使用权,再退出区释放临界区的使用权。
cobegin
process Pi()
{
.....//与临界资源无关的部分
lock out interrupts;//关中断
临界区;
unlock out interrupts;//开中断
....
}
coend
int TS(int s)
{
if(s)
return 1;
else
{
s=1;
return 0;
}
}
cobegin
process Pi()
{
.....//与临界资源无关的部分
while(TS(s));
临界区;
s=0;
....
}
coend
在进入临界区之前首先用TS指令测试s,若s为0则表明没有其他进程使用此临界区,于是本进程可以进入临界区,进入临界区以后s=1,阻止其他进程进入,当离开临界区时,设置s=0,让其他进程进入临界区。否则,一直用while测试。
void swap(int *a,int *b)
{
int temp=*a;
*a=*b;
*b=temp;
}
int s=0;
cobegin
process Pi()
{
.....
int key=1;
do{
swap(&s,&key);
}while(key);
临界区
s=0
........
}
coend
为临界资源设置整型全局变量s: s=0—>临界区空闲,s=1—>临界区被占用。
为每个进程设置整型局部变量key,如果s=0ANDkey=1,允许进入临界区。由于交换,进入临界区以后s=1,key=0,为了使其他进程可以进入临界区,在离开临界区时使s=0。
进程P1
....
while(T2);//检测P2是否在临界区,T2=1则P2在临界区
T1=1;
临界区
T1=0;
.......
进程P2
....
while(T1);//检测P2是否在临界区,T2=1则P2在临界区
T2=1;
临界区
T2=0;
.......
缺点:当T1=T2=0时,P1和P2都会进入临界区
进程P1
....
T1=1;
while(T2);//检测P2是否在临界区,T2=1则P2在临界区
T1=1;
临界区
T1=0;
.......
进程P2
....
T2=1;//表示P2在临界区
while(T1);//检测P2是否在临界区,T2=1则P2在临界区
T2=1;
临界区
T2=0;
.......
缺点:当T1=T2=1时,P1 P2都不能进入临界区
T1 T2与两标志进程互斥算法相同,第3个标志T是一个公共标志,用来表示允许进入临界区的进程标号,T=1表示运行进程1进入临界区
进程P1
....
T1=1;
T=2;//允许P2进入临界区
while(T2==1&&T==2);//检测P2是否在临界区,T2=1则P2在临界区
T1=1;
临界区
T1=0;
.......
进程P2
....
T2=1;//表示P2在临界区
T=1;//运行P1进入临界区
while(T1);//检测P2是否在临界区,T2=1则P2在临界区
T2=1;
临界区
T2=0;
.......
三标志未算法相比较于两标志进程算法的形式二,只是加了一个T,它不会出现两标志的同时进入和同时不能进入的情况,因为当满足T1=T2=1时,T是不可能同时满足两个while的,T的数值决定了哪一个进程可以进入临界区。而T1=T2=0的情况是不能发生的,因为每个进程在进入临界区之前都将自己的Ti设置为1。