(本文是笔者在看jyy操作系统P4后做的笔记)
Peterson算法是一个实现互斥锁的并发程序设计算法,可以控制两个线程访问一个共享的单用户资源而不发生访问冲突。
Peterson算法的本质是一种谦让模式,当两个线程的其中一个想进入临界区时,先观察一下另一个是否也想进入临界区,如果是,则让另一线程先进。
实现方式:
- 每个线程都拥有一个旗帜,表示他们是否想进入临界区(在即将进入临界区前,则会举起旗帜,在临界区结束后应放下旗帜)
- 临界区上有一个代表允许进入的线程的标识,当两个线程都想进入临界区时,标识上的线程率先进入
- 每个线程在举起自己的旗帜的同时把标识修改为另一线程,然后观察对方是否举起旗帜,只有在对方没有举起旗帜或对方举起旗帜但此时标识上指示的是自己时,该线程才可进入临界区(这句话隐含了先举起旗帜的线程一定会先进入临界区,大家可自行推理)
代码:
#define T1 1
#define T2 2
int turn;//标识
bool flag1 = false, flag2 = false;//旗帜
void thread1(){
//临界区前代码块
......
flag1 = true;//举起旗帜,申请进入临界区
while(flag2 && turn == T2);//空循环,进入临界区前的判断,只有满足条件才可进入临界区
//此处写成while(1)if(!flag2 || turn == T1)break;好像要好懂一点
//临界区代码块
......
flag1 = false;//降下旗帜,释放临界区以便另一线程进入
//临界区后代码块(即剩余区)
......
}
void thread2(){
//临界区前代码块
......
flag2 = true;
while(flag1 && turn == T1);
//临界区代码块
......
flag2 = false;
//临界区后代码块
......
}
Peterson算法可以保证:
- 不会让两个线程同时进入临界区
- 不会让进程进入死循环(即都不能进入临界区)
- 每个线程都可以进入临界区(不会让线程饿死在临界区外)