2.3_2 进程互斥的软件实现方法

2.3_2 进程互斥的软件实现方法

进程互斥的软件实现方法 单标志法 双标志先检查 双标志后检查 Peterson算法

单标志法

这块儿代码是基于我看的B站视频改进的,我认为他的代码逻辑不很好理解,所以,可能不是很正确

java 复制代码
int turn = 0;	//turn表示当前允许进入临界区的进程号
while(true){
    //P0进程					   	   
    while(turn==0){					
        critical section;				
        turn = 1;						
        remainder section;				
    }
    
    //P1进程
    while(turn==1){
        critical section;
        turn = 0;
        remainder section;
    }
}

注意:上面P0和P1部分的代码是并发执行的

turn的初始值为0,刚开始只允许P0进程进入临界区。

P0进程的时间片结束后,turn变为1,此时只有P1进程可以访问临界区。

该算法可以实现同一时刻最多只允许一个进程访问临界区

主要问题:违背"空闲让进"原则

只能按P0→P1→P0→P1→ ...... 这样轮流访问。这种必须"轮流访问"带来的问题是,如果此时允许进入临界区的进程是P0,而P0一直不访问临界区,那么虽然此时临界区空闲,但是并不允许P1访问。

双标志法先检查

算法思想:

设置一个布尔型数组 flag\[\],数组中各个元素用来标记各进程是否处于临界区内,比如"flag0=ture"意味着0号进程P0现在正在临界区内。每个进程在进入临界区之前先检查当前有没有别的进程处于临界区内。如果没有,则把自身对应的标志flagi设为true,之后开始访问临界区。

java 复制代码
bool flag[2];
flag[0]=false;
flag[1]=false;

while(true){
    //P0进程
    while(flag[1]!=1){
        flag[0]=true;
        critical section;
        flag[0]=false;
        remainder section;
    }
    
    //P1进程
    while(flag[0]!=1){
        falg[1]=true;
        critical section;
        flag[1]=false;
        remainder section;
    }
}

注意:上面P0和P1部分的代码是并发执行的

主要问题 :如果按照7行、15行、8行、16行这样的顺序来执行的话,临界区会被P0和P1同时访问。违反"忙则等待"原则

问题在于,进入区的"检查"和"上锁"两个处理不是一气呵成的,"检查"后"上锁"前有可能发生进程切换。

双标志后检查

算法思想:双标志先检查法的改版。前一个算法的问题是先"检查"后"上锁",但是这两个操作又无法一气呵成,因此导致了两个进程同时进入临界区的问题。因此,人们又想到先"上锁"后"检查"的方法,来避免上述问题。

java 复制代码
bool flag[2];
flag[0]=false;
flag[1]=false;

while(true){
    
    //P0进程
    flag[0]=true;8
    while(flag[1]!=1){9
        critical section;
        flag[0]=false;
        remainder section;
    }
    
    //P1进程
    flag[1]=true;16
    while(flag[0]!=1){17
        critical section;
        flag[1]=false;
        remainder section;
    }
}

注意:上面P0和P1部分的代码是并发执行的

主要问题:如果按照8行、16行、9行、17行这样的顺序来执行,每个进程都发现对面上锁了,都无法访问。

因此,双标志后检查法虽然解决了"忙则等待"的问题,但是又违背了"空闲让进"和"有限等待"原则,会因各进程都长期无法访问临界资源而产生"饥饿"现象

Peterson算法

算法思想:结合双标志法、单标志法的思想。如果双方都争着想进入临界区,那可以让进程尝试"孔融让梨"(谦让)。做一个有礼貌的进程。

java 复制代码
bool flag[2];
int turn = 0;	//表示优先让哪个进程进入临界区

//P0进程
flag[0]=true;
turn=1;
while(flag[1] && turn==1);	//如果为真,则卡在这一步
critical section;
flag[0]=false;
remainder section;

//P1进程
flag[1]=true;
turn=0;
while(flag[0] && turn==0);	//如果为真,则卡在这一步
critical section;
flag[1]=false;
remainder section;

Peterson算法用软件方法解决了进程互斥问题,遵循了空闲忙进、忙则等待、有限等待三个原则 ,但是依然未遵循让权等待的原则。

即:如果一个进程一直进不了临界区,那么会一直被卡在while循环。但是自己还在CPU上运行,不断检查while循环的条件是否得到满足。虽然这个进程进不了临界区,但是依然占用CPU资源


知识回顾与重要考点

相关推荐
kkeeper~9 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
wabs66610 小时前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
2401_8769641310 小时前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
嗝o゚11 小时前
CANN GE 算子融合——融合算法与调度策略
算法·昇腾·cann·ge
小江的记录本11 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
Ulyanov13 小时前
用声明式语法重新定义Python桌面UI:QML+PySide6现代开发入门(一)
开发语言·python·算法·ui·系统仿真·雷达电子对抗仿真
数据科学小丫13 小时前
特征工程处理
人工智能·算法·机器学习
z落落13 小时前
C#参数区别
java·算法·c#
c2385614 小时前
vector(下)
数据结构·算法
z落落14 小时前
C# 冒泡排序+选择排序 + Array.Sort 自定义排序
数据结构·算法