互斥与同步

一、竞争条件
1.什么是竞争条件?
  两个或者多个进程读写某些共享数据,而最后的结果取决于进程运行的精确时序,称为竞争条件

2.怎样避免竞争条件?
  要避免这种错误,关键是找出某种途径来阻止多个进程同时读写共享的数据。换言之,我们需要互斥!即以某种手段确保当一个进程在使用一个共享变量或者文件时,其他进程不能做同样的操作。

3.什么叫临界区?
  我们把对共享内存进行访问的程序片段称作临界区域或者临界区。使得两个进程不可能同时处于临界区中,就能够避免竞争条件。

4.一个好的避免出现竞争条件的解决方案,需要满足以下四个条件:
  a).任何两个进程不能同时处于临界区。
  b).不应该对CPU的速度和数量做任何假设。
  c).临界区外运行的进程不得阻塞其他进程。
  d).不得使进程无限期等待进入临界区。
  
二、互斥方式
  2.1.忙等待的互斥
  
  1).屏蔽中断
  在单处理器系统中,最简单的办法是使每个进程在刚刚进入临界区后立即屏蔽所有中断,并在将要离开之前再打开中断。屏蔽中断后,时钟中断也被屏蔽。CPU只有在发生时钟中断或其他中断时才会进行进程切换。所以,在屏蔽中断后CPU将不会被切换到其他进程。于是,一旦某个进程屏蔽中断后,它就可以检查和修改内存,而不必担心其他进程介入。
优点:足够简单、明了。
缺点:把屏蔽中断的权力交给用户进程是不明智的。设想一下,如果一个用户进程屏蔽中断后不再打开,其结果将会如何?
   只能适用于单CPU系统。如果系统是多处理器,则屏蔽中断仅仅对执行disable指令的那个CPU有效,其他CPU仍将继续运行并切换进程,而且可以访问共享内存。
   
  2).锁变量
  这是一种软件解决方案。设想有一个共享(锁)变量,其初始值为0,当一个进程想进入其临界区时,它首先测试这把锁。如果该锁的值为0,则该进程将其设置为1并进入临界区。若这把锁的值已经为1,则该进程将等待直到其值变为0。
  疏漏:假设一个进程读出锁变量的值并发现它为0,而恰好在它将其值设置为1之前,另一个进程被调度运行,将该锁变量设置为1。当第一个进程再次运行时,它同样也将该锁设置为1,并进入临界区。此时同时有两个进程进入临界区。所以这种方案不可行!
  
  3).严格轮换法
  设置一个整型变量turn,初始值为0,用于记录轮到哪个进程进入临界区,并检查或更新共享内存。开始时,进程0检查turn,发现其值为0,于是进入临界区。进程1也发现其值为0,所以在一个等待循环中不停地测试turn,看其值何时变为1,等到其值变为1,则进入临界区。
这种方式可用下面的两段代码描述:
  进程0:

while(TRUE){
    while (turn != 0);
    critical_region();
    turn = 1;
    noncritical_region();
    }

  进程1:

while(TRUE){
    while (turn != 1);
    critical_region();
    turn = 0;
    noncritical_region();
    }

  可以看到,进程0在离开临界区前,它将turn的值设置为1,以便允许进程1进入临界区。
  优点:简单、有效;
  缺点:性能较低,CPU的利用率不高,因为涉及到忙等待的问题。连续测试一个变量直到某个值出现为止,称为忙等待。只有在有理由认为等待时间是非常短的情况下,才能使用忙等待。用于忙等待的锁,称为自旋锁
  试着考虑这样一种情况:假设turn的值为0,此时进程0先进入临界区,现在进程0很快就执行完其整个循环,它退出临界区,并将trun的值设置为1。此时,turn的值为1,两个进程都在其临界区外执行。突然,进程0结束了非临界区的操作,并且尝试进入临界区。但是,此时它无法进入临界区,因为turn的值为1,而此时进程1还在忙于执行非临界区的操作,进程0只有继续while循环,直到进程1把turn的值改为0。这说明在一个进程比另外一个进程慢了很多的情况下,轮流进入临界区并不是一个好办法。这种情况违反了前面叙述的条件3:进程0被一个临界区之外的进程阻塞。
  
  4).Peterson算法
  这种方法是由两个ANSI C编写的过程:

#define FALSE 0
#define TRUE 1
#define N 2
int turn;
int interested[N];

void enter_region(int process)
{
    int other;
    other = 1 - process;
    interested[process] = TRUE;
    turn = process;
    while(turn == process && interested[other] == TRUE);
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值