概述
并发执行的程序会出现很多问题,一个简单的例子是生产者-消费者问题。
生产者生产资源(执行count++
)的同时消费者消耗(count--
),count
的初值是5,理想结果是count=5
,但如果同时执行两条语句,对于生产者和消费者,他们的count
都是5,那么最后根据恢复的情况不同(生产者后执行完或消费者后执行完),最后会导致count
还有4、6两种情况。
这是并发带来的问题,即多个进程并发访问和操作同一数据且执行结果与访问发生的特定顺序有关,称为竞争条件(race condition),为了避免这一个问题,需要确保一段时间只有一个进程能操作变量count
需要避免这些问题,因此需要进程同步(Process synchronization)和协调(coordination)
临界区问题
临界区(critical section)
是指多个进程中能够改变共同变量,更新同一个表,访问同一个文件的代码区段,当其中一个进程进入临界区的时候,没有任何其他进程能够进入临界区。
临界区问题
是设计一个协议,让进程能够协作。每个进程必须通过请求进入临界区,实现这一请求的代码称为进入区(entry section),临界区之后会有退出区(exit section),其他代码称为剩余区(remainder section),其通用结构如下。
临界区问题的答案需求
- 互斥(mutual exclusion)
- 前进(progress),如果没有进程在临界区,且有进程需要进入临界区,那么只有那些不在剩余区内执行的进程可以参与选择,并且这种选择不能无限推迟。
- 有限等待(bounded waiting),从一个进程做出进入临界区的请求,直到该请求允许为止,其他程序允许进入其临界区的次数有上限。
- 假定每个进程的执行速度不为0
- 无法对n个进程的相对速度做任何假设。
在操作系统的临界区问题中,通过抢占内核和非抢占内核两种方式来处理,很显然非抢占内核不会导致竞争条件,而对于抢占内核,则需要精心设计以避免竞争条件
Peterson算法
该算法是一个经典的基于软件的临界区问题的解答,但只适用于两个进程在临界区和剩余区间交替执行。
Peterson算法在两个进程间共享两个数据,turn表示哪个进程可以进入临界区,flag表示哪个进程想进入临界区。
int turn;
boolean flag[2];
在该算法中的两个进程,假设为pi和pj,当使用pi时候,用pj来表示另一个进程,即j=1-i
。
该算法在进程i中的结构如下:
do{
flag[i] = TRUE;
turn = j;
while(flag[j] && turn == j);
//临界区
flag[i] = FALSE;
//剩余区
}while(TRUE);
这个算法其实是两个进程之间互相“谦让”的:如果对方想进,并且turn是对方的,那么自己就进入等待区。
如果两个进程同时想进入临界区,那么会同时改变turn的值,但turn最后只会保持为一个值,也就是竞争是平等的,但如果争不过,那就不争了
通过一些论证可以说明Peterson算法的解答是正确的(也即满足了互斥成立,前进要求满足,有限等待要求满足)
硬件同步
Peterson算法是基于软件的解答,而硬件也可以有一些机制来解决临界区问题。
其中,单处理器和多处理器的情况不太一样:
- 对于单处理器,临界区问题的解决很简单:只需要在修改共享变量时禁止中断出现即可(也就是要求非强占),这样能确保当前指令序列的执行不会中断。
- 对于多处理器,问题要复杂的多,禁止中断的操作要传递到所有处理器上会很费时,从而降低系统效率。
因此,现代计算机系统提供了特殊的硬件指令来相对简单的解决临界区问题,现在将这种指令的概念抽象成代码,可以描述成下文的形式:
//TestAndSet()指令的定义
boolean TestAndSet(boolean *target){
boolean rv = * target;
*target = TRUE;
return rv;
}
//使用TestAndSet的互斥实现
do{
while(TestAndSetLock(&lock));
//临界区
lock = FALSE:
//剩余区
}while(TRUE);
//Swap() 指令的定义
void Swap(boolean *a,boolean *b){
boolean temp = *a;
*a = *b;
*b = temp;
}
//使用Swap()指令的互斥实现
do{
key = TRUE;
while(key == TRUE)
swap(&lock,&key);
//临界区
lock = FALSE;
//剩余区
}while(TRUE);
在这里,课本提到,上述的两个方法解决了互斥,但没有解决有限等待的问题,我一直没有相同,在查阅其他的文章之后有人谈到他的理解