@yanglt7
2018-05-22T07:31:39.000000Z
字数 4470
阅读 1111
操作系统
9.1 背景
9.2 现实生活中的同步问题
| 相互感知的程度 | 交互关系 | 进程间的影响 |
|---|---|---|
| 相互不感知(完全不了解其他进程的存在) | 独立 | 一个进程的操作催其他进程的结果无影响 |
| 间接感知(双方都与第三方交互,如共享资源) | 通过共享进行协作 | 一个进程的结果依赖于共享资源的状态 |
| 直接感知(双方直接交互,如通信) | 通过通信进行协作 | 一个进程的结果依赖于从其他进程获得的信息 |
9.3 临界区(critical section)
9.4 禁用硬件中断
没有中断,没有上下文切换,因此没有并发,整个系统由当前进程独占
现代计算机体系结构都提供指令来实现禁用中断
进入临界区
禁止所有中断,并保存标志
离开临界区
禁用中断中,进程无法被停止
临界区可能很长
要小心使用
9.5 基于软件的同步方法
int turn = 0turn == i//表示允许进入临界区的线程
do {while (turn != i);//条件不成立就可以进入临界区critical sectiontrun = j;remainder section} while (1);
int flag[2];flag[0] = flag[1] = 0;flag[i] == 1;//表示线程Ti是否在临界区
do {while (flag[j] == 1);flag[i] = 1;critical sectionflag[i] = 0;remainder section} while (1);
int flag[2];flag[0] = flag[1] = 0;flag[i] == 1;//表示线程Ti想要进入临界区
do {flag[i] = 1;while (flag[j] == 1);critical sectionflag[i] = 0;remainder section} whlie (1);
int turn;boolean flag[];//表示进程是否准备好进入临界区
flag[i] = true;turn = j;while (flag[j] && turn ==j) //两个条件只要一个不满足就能进去
flag[i] = false;
do {flag[i] = true;turn = j;while (flag[j] && turn == j);critical sectionflag[i] = false;remainder section} while (1);
flag[0] := false;flag[1] := false;turn := 0;//orldo {flag[i] = true;while flag[j] == true {if turn != i {flag[i] := falsewhile turn != i{}flag[i] := true}}critical sectionturn := jflag[i] = false;remainder section} while (true);
| turn | i-1 | i | i+1 | i+2 | n-1 | 0 | ||
|---|---|---|---|---|---|---|---|---|
| 处理循环 | 处理循环 | 处理循环 | 处理循环 | 处理循环 | 处理循环 | 处理循环 | 处理循环 | 处理循环 |
线程Ti退出时,把turn改成下一个请求进程
特点:
复杂:
需要忙等待
9.6 更高级的抽象方法
硬件提供了一些同步原语
操作系统提供更高级的编程抽象来简化进程同步
锁是一个抽象的数据结构
Lock :: Acquire()
Lock :: Release()
使用锁来控制临界区访问
lock_next_pid -> Acquire();new_pid = next_pid++;lock_next_pid -> Release();
测试和置位(Test-and-Set)指令
交换指令(exchange)
class Lock {int value = 0;//初始化锁里的初值为0}Lock :: Acquire() {while (test-and-set(value));//spin//构造它的请求操作原语,即用TS指令去把value的值读出来,并且往里写1。//如果是1,则这个操作就相当于是个检查,如果是0,则设为1,循环结束。}
如果锁被释放,那么TS指令读取0并将值设置1
如果锁处于忙状态,那么TS指令读取1并将值设置为1
Lock :: Release() {value = 0;}
Lock :: Acquire() {while (test-and-set(value));//spin}Lock :: Release() {value = 0;}
class Lock {int value = 0;WaitQueue q;//在锁的数据结构里加上一个等待队列,即等待这个锁的相应的进程所排的队列}Lock :: Acquire() {while (test-and-set(value));{and this TCB to wait queue q;schedule();}}
Lock :: Release() {value = 0;//表示释放锁remove one thread t from q;wakeup(t);//将线程从等待队列放到就绪队列。等待时,就处于放弃CPU使用权的状态,实现了让权等待}
优点
缺点
锁是一种高级的同步抽象方法
常用的三种同步实现方法