最常用,最简单,最好理解的方法就是关中断,因为操作系统的线程切换是通过中断进行的,只要中断关掉,程序只能继续执行:
关中断;
临界区;
开中断;
第二种硬件方法是通过原子指令,不同CPU支持不同的原子指令。
线程1:
while(turn!=0);
临界区;
turn=1;
线程2:
while(turn!=1);
临界区;
turn=0;
这种方法的缺点是,一旦一个程序停止,另一个就无法进入临界区。
线程1:
while(flag[j]);
flag[i]=true;
临界区;
flag[i]=false;
线程2:
while(flag[i]);
flag[j]=true;
临界区;
flag[j]=false;
先检查标志位,缺点是可能同时进入临界区。
线程1:
flag[i]=true;
while(flag[j]);
临界区;
flag[i]=false;
线程2:
flag[j]=true;
while(flag[i]);
临界区;
flag[j]=false;
后检查标志位,缺点是可能导致相互等待,出现饥饿现象。
线程1:
flag[i]=true;turn=j;
while(flag[j] && turn==j);
临界区;
flag[i]=false;
线程2:
flag[j]=true;turn=i;
while(flag[i] && turn=i;);
临界区;
flag[j]=false;
这种方法是算法1和算法3的结合,利用flag解决互斥访问,利用turn解决“饥饿”现象。