解决临界区(互斥)的软件方法-Dekker算法和Peterson算法

这里写图片描述
Dekker算法初步设想【保证了互斥】:让两个进程共享一个全局变量turn,【其初值为0或1】。如果turn==i,那么进程Pi允许在其临界区内执行。
—为了控制两个进程互斥进入临界区,可以让两个进程轮流进入临界区。
—当一个进程正在临界区执行时,另一个进程就不能进入临界区,而在临界区外等待。

这里写图片描述

这里写图片描述
1.为何是“强制交替”?
Turn=0时,无论CS空闲与否,即使P1就绪想要进入CS也【不会成功】,必须等待P0进入CS执行,退出后才能进入CS。
【关键】turn=0时P1:while(turn!=1);会一直陷入循环【忙等】,直至P0运行一次,turn值改为1,P1进程才可以运行。(一般turn=0是P1执行的结果,即P1执行后P1不能再次执行,必须换到P0执行。所以是“强制交替”)
2.为何不满足“前进要求”,任何进程在CS 区内外失败,其他进程都可能因为等待使用CS而无法向前推进?
可能恰恰是因为“强制交替”,假若P0和P1两个进程交替,P0进程如果没有修改turn=1就死了,那么P1就永远无法运行。

Dekker算法-改进一:
【初步设想】让两个进程共享一个全局变量turn,【其初值为0或1】。如果turn==i,那么进程Pi允许在其临界区内执行。
【改进一】使用全局共享数组flag标志CS状态:
flag[0]或flag[1]=true:表示P0或P1占用CS,
flag[0]或flag[1]=false:表示CS空闲。
这里写图片描述
这里写图片描述
1.进程在CS内失败?什么意思?
【未解决】2017.11.29
2.不能实现互斥,P0和P1可能同时进入临界区。【初步设想是实现了互斥的】

这里写图片描述
Dekker算法-改进二【改为先置标志位】:
这里写图片描述
这里写图片描述
这里写图片描述
Dekker算法-【最终成功版】:
这里写图片描述

flag[2]用来表示是否想要使用关键区,turn用来表示具有访问权限的进程ID。(重点看注释,通过注释,挺好理解的哟~)

#include<stdio.h>  
#include<stdlib.h>  
#include<pthread.h>  
#define true 1  
#define false 0  
typedef int bool;  
bool flag[2];  
int turn;  
void visit(int num)  
{  
        sleep(1);  
        printf("P%d is visting\n",num);  
}  
void P0()  
{  
        while(true)  
        {  
                flag[0] = true;//P0想使用关键区。  
                while(flag[1])//检查P1是不是也想用?  
                {  
                        if(turn == 1)//如果P1想用,则查看P1是否具有访问权限?  
                        {  
                                flag[0] = false;//如果有,则P0放弃。  
                                while(turn == 1);//检查turn是否属于P1。  
                                flag[0] = true;//P0想使用。  
                        }  
     
Dekker算法Peterson算法都是经典的并发控制协议,用于解决计算机系统中两个进程(或线程)互斥地访问共享资源的问题。 **Dekker算法**: Dekker算法是由英国软件工程师Edsger W. Dijkstra的学生Peter J. Dekker于1968年提出的。它是一种简单的二阶段锁协议,采用信号量机制来保证同步。算法步骤如下: 1. 每个进程获取第一个信号量(资源未被占用)。 2. 进程尝试获取第二个信号量(检查另一个进程是否已进入临界区)。 3. 如果失败,则释放第一个信号量并等待;如果成功,进入临界区执行操作。 4. 执行完毕后,释放两个信号量,允许其他进程进入。 **Peterson算法**: Peterson算法由Edsger Dijkstra的学生James H. Peterson于1981年设计,它是在无信号量环境下的一种简单、可扩展的互斥算法。这个算法适用于单处理器多进程环境,每个进程有两对标志位(分别是进程P的旗p0p1,以及另一个进程Q的旗q0q1)。 1. 每个进程有一个条件变量cv,并初始化为自己的flag状态。 2. 进程检查对方的flag是否满足互斥条件(即对方的p1==0q1==0),如果不满足,就进入等待状态,释放自己的资源。 3. 等待的进程只有在对方设置了自己的flag(如P等待q1变为1,Q等待p1变为1)后才会唤醒,并进入临界区执行操作。 4. 在临界区内修改flag并唤醒对方(如P将p1设为0,然后唤醒等待q1的Q)。 5. 退出临界区后恢复flag,继续检查条件并可能重新进入等待状态。 这两个算法都是理论上的教学示例,它们都存在局限性,比如性能开销大、不适合大规模并发等。现代操作系统通常使用更高级的同步原语更复杂的锁机制来实现互斥同步。如果你感兴趣,可以进一步研究这些算法背后的原理适用场景。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值