竞争条件和临界区
最后更新于:2022-04-02 04:08:44
[TOC]
## 临界区
1. 访问共享资源的程序片段
2. 资源并不能被同时使用(如:打印机)
## 解决临界区的办法
### 互斥
最简单的办法是让临界区互斥( mutual exclusion),就是同时不会有两段程序在临界区。严格说,应该满足4个条件:
1. 任何两个进程不同时在临界区
2. 不对 CPU 数量和速度做任何假设
3. 临界区外运行的进程不得阻塞其他进程
4. 不得使进程过长等待临界区
#### 将临界区上锁
#### 进程在临界区屏蔽中断
屏蔽中断可以**阻止进程切换**。将屏蔽中断的能力下放给用户进行临界区管理。
(并不推荐)
#### Perterson 算法(互斥算法-严格轮换法)
初始化
```
int turn = 0 ;
```
进程1
```
while(ture){
while(turn != 0){
// 临界区
turn=1;
// 非临界区
}
}
```
进程2
```
while(ture){
while(turn != 1){
// 临界区
turn=0;
// 非临界区
}
}
```
问题:如果进程2的非临界区运算很慢,会出现什么情况?
答: 进程2不在临界区中,但是由于非临界区执行慢,会影响
如果改进
- 每个线程进入临界区之前都标记自己对临界区资源感兴趣
- 进程执行完临界区后,不应该主动交出控制权(设置turn),而是观察其他进程对临界
区的资源感不感兴趣
#### 改进 Peterson 算法
虽然现在都是依靠硬件来实现互斥,但是此方案可用于分布式执行等其他领域提供灵感
```
int[] interested = new int[2];
int turn = 0;
void enterRegin(int pod){
int other = 1- pid
interested[pid]=true;
turn = pid;
while(turn == pid && interested[other]);
}
void leaveRegion(int pid) {interested[pid]==false;}
```
';