一个进程访问临界资源,其他进程就需要等待。
对临界资源互斥访问大体上分为四个部分:
保证互斥访问需要遵循以下原则:
算法思想:利用一个标记,表示当前允许进入临界区的进程号
int turn = 0;
//p0
while (turn != 0);
critical section;
turn = 1;
remainder section;//p1
while (turn != 1);
critical section
turn = 0;
remainder section;
只能轮流使用,如果只有一个进程,那么此时就无法再进行下去,违反空闲让进原则。
算法思想:设置一个布尔型数组,用于标记各个进程想要进入临界区的意愿。
bool flag[2];
flag[0] = false;
flag[0] = false;//p0
while (flag[1]);
flag[0] = true;
critical section;
falg[0] = false;
remainder section;//p1
while (flag[0]);
flag[1] = true;
critical section;
falg[1] = false;
remainder section;
问题:在并发运行的环境下,可能两个都进入了while循环,违背了忙则等待原则。
与先检查类似,只是先表明意愿,再看别人用不用
bool flag[2];
flag[0] = false;
flag[0] = false;//p0
flag[0] = true;
while (flag[1]);
critical section;
falg[0] = false;
remainder section;//p1
flag[1] = true;
while (flag[0]);
critical section;
falg[1] = false;
remainder section;
问题:在并发条件下,可能两个进程都设置了true,不会产生忙则等待,但是违背空闲让进与有限等待。
算法:先表明自己想要用临界资源,但是也表示可以让对方先用。
bool flag[2];
int turn = 0;//p0
flag[0] = true;
turn = 1;
while (flag[1] && turn == 1);
critical section;
flag[0] = false;
remainder section;//p1
flag[1] = true;
turn = 0;
while (flag[0] && turn == 0);
critical section;
flag[1] = false;
remainder section;
原理解析,就算在并发条件下,A表明自己想用,B也想用,但是只要是最后一个人说出他想让对方先用,那么决定权就放弃给对方。同时放权这个动作只会进行一次,此时对方不会再进行放权这个动作,就会直接进行访问临界区。所以不会有同时访问临界区的问题。
满足空闲让进,忙则等待,有限等待,但是依旧不满足放权等待。
本质思想:让表明自己想用与进入临界区那个while循环检查合二为一,就不会出现同时进入临界区这个问题。那么就需要让硬件直接实现让这两句话实现原子性。
由硬件直接实现,执行过程不被中断。
bool TestAndSet (bool *lock){ //硬件直接实现,函数只是说明硬件执行逻辑bool old;old = *lock;*lock = true;return old;
}while (TestAndSet(&lock));
跟tsl差不多
Swap (bool *a, bool *b){ //硬件直接实现,保证原子性bool tmp;temp = *a;*a = *b;*b = tmp;
}bool old = true;
while (old == true)Swap(&lock, &old);
critical section;