【av68676164(p23-p24)】临界区和锁
4.4.1 临界资源和临界区
临界资源(Critical Resource)
一次只允许一个进程独占访问(使用)的资源
例:例子中的共享变量i
临界区(Critical Section)
进程中访问临界资源的程序段
// 程序A
i = 100;
printf("A:i=%d", i);
// 程序B
i = 200;
printf("B:i=%d", i);
临界区和临界资源的访问特点
- 具有排他性
- 并发进程不能同时进入临界区
设计临界区访问机制的四个原则
- 忙则等待:当临界区忙时,其他进程必须在临界区外等待
- 空闲让进:当无进程处于临界区时,任何有权进程可以进入临界区
- 有限等待:进程进入临界区的请求应在有限时间内满足
- 思考:临界区的设置大些好还是小些好?
- 不能随意扩大(其他进程等待更长时间)
- 不能太小(达不到目的)
- 思考:临界区的设置大些好还是小些好?
- 让权等待:等待进程放弃CPU(让其他进程有机会得到CPU)
4.4.2 锁机制
基本原理
设置一个“标志”S:
- 表明临界资源“可用”还是“不可用”?1:0
进入临界区之前检查标志是否“可用”?——上锁操作
- 若为“不可用”状态:进程在临界区外等待
- 若为“可用”状态
- 访问临界资源
- 将标志修改为“不可用”
离开临界区时将标志修改为“可用”状态——开锁操作
上锁操作
步骤
- 检查锁S的状态(0或1)
- 如果S=0,则返回第一步
- 如果S=1,则置其为0
// 上锁源语
void Lock(S) {
test:
if (S == 0) {
goto test;
} else {
S = 0; // 上锁
}
}
开锁操作
步骤
- 把锁S的状态置1
// 开锁愿语
void Unlock(S) {
S = 1;
}
用锁机制访问临界区
- 初始化锁的状态S=1(可用)
- 进入临界区前执行上锁Lock(s)操作
- 离开临界区之后执行开锁unlock(s)操作
graph TB
S=1-->上锁Lock
上锁Lock-->临界区
临界区-->开锁Unlock