一、软件算法
peterson算法:为每个进程设置标志inside[i],当标志为true时表示此进程要求进入临界区;此外再设置指示器turn指示由哪个进程进入临界区
bool inside[2]; inside[0] = false; inside[1] = false; enum{0,1} turn; cobegin process p0() { inside[0] = true; //上锁 turn = 1; while(inside[1]&&turn==1); /*临界区*/ inside[0] = false; } process P1() { inside[1] = true; turn = 0; while(inside[0]&&turn==0); /*临界区*/ inside[1] = false; } coend
任意进程进入临界区的条件:对方不想进入临界区,且对方不在临界区
因此,任何进程均可多次进入临界区,不会出现饥饿现象
二、硬件设施
(1)关中断
进入临界区时关中断,随后时钟中断、进程上下文切换等均被屏蔽,退出临界区时开中断
缺点:不适合作为通用互斥机制,关中断时间过长影响性能和系统效率,不适合多处理器系统,该权力赋予用户过于危险
(2)测试并建立指令
一条不可分割的指令TS(&x)完成测试锁、挂上锁
bool TS(bool &x){ if(x){ x == false; return true; } else return false; } bool s = true; cobegin process Pi(){ while(!TS(s)); /*临界区*/ s = true; //开锁 } coned
(3)对换指令
每个进程进入临界区前先定义一个真值,与这把锁进行交换
void SWAP(bool &a , bool &b){ bool temp = a; a = b; b = temp; } bool lock = false; cebegin process Pi(){ bool keyi = true; do{ SWAP(keyi , lock) }while(keyi); /*临界区*/ SWAP(keyi , lock); } coend
缺点:指令在进入临界区前会忙式等待