1、进程互斥的软件实现方法

  • 单标志法
  • 双标志法
  • 双标志后检查
  • Peterson算法

2、单标志法

算法思想:两个进程在访问完临界区后会把使用临界区的权限转交给另一个进程,也就是说每个进程进入临界区的权限只能被另一个进程赋予;

通过代码来分析,在系统中会设置一个turn的变量:

int turn = 0;  //表示当前允许进入临界区的进程号;

默认turn的初始值为0,刚开始可以由0号进程P0P_0P0​进入临界区进行访问;

P0P_0P0​和P1P_1P1​对临界区进行访问的代码分别是:

# p0
while (turn !=0);  (1) // 进入区
critical section;  (2) // 临界区
turn = 1;          (3) // 退出区
remainder section; (4) // 剩余区# p1
while (turn !=1);  (5) // 进入区
critical section;  (6) // 临界区
turn = 0;          (7) // 退出区
remainder section; (8) // 剩余区

turn的初值为0,即刚开始只允许0号进程P0P_0P0​进入临界区;如果刚开始是P1P_1P1​进程,P1P_1P1​进程在进入区进行判断时,turn=0,因为while(turn != 1)循环条件满足,所以P1P_1P1​进程会一直在循环语句中循环,一直到分配给P1P_1P1​的时间片用完,发生调度,将P0P_0P0​进程放到处理机上运行,P0P_0P0​进程执行while(turn!=0)不符合循环条件,所以会跳过循环,进入临界区,访问临界区;在P−0P-0P−0访问临界区时发生进程调度调用P1P_1P1​时,由于turn=0,所以进程P1P_1P1​依然无法进入临界区;

一直到P0P_0P0​访问完临界区之后,会在退出区中修改turn的值,把turn修改为turn=1,把访问临界区的权限交给进程P1P_1P1​;这时候当调度P1P_1P1​进程时,P1P_1P1​可以顺利进入临界区,当P1P_1P1​进入退出区时,重新把turn修改为turn=0;

通过以上分析,我们可以知道该算法可以实现“同一时刻最多只允许一个进程访问临界区”;

单标志法中,turn表示当前允许进入临界区的进程号,而只有当前允许进入临界区的进程在访问了临界区之后,才回修改turn值。也就是说,对于临界区的访问,一定是按照p0−>p1−>p0−>p1−>...p_0->p_1->p_0->p_1->...p0​−>p1​−>p0​−>p1​−>...这样轮流访问的。

这种必须“轮流访问”带来的问题是,如果此时允许进入临界区的进程是P0P_0P0​,而P0P_0P0​一直不访问临界区,那么虽然此时临界区空闲,但是并不允许P1P_1P1​访问;

因此,单标志法存在的主要问题是:违背“空闲让进”原则;

3、双标志先检查法

算法思想:设置一个布尔型数组flag[],数组中各个元素用来标记各进程想进入临界区的意愿,比如"flag[0]=True"意味着0号进程P0P_0P0​现在想要进入临界区。每个进程在进入临界区之前先检查当前有没有别的进程想进入临界区,如果没有,则把自身对应的标志flag[i]设置为True,之后开始访问临界区;

bool flag[2];    // 表示进入临界区意愿的数组
flag[0] = False;
flag[1] = False; // 刚开始设置为两个进程都不想进入临界区

假设此时系统中只有两个进程,两个进程的代码如下:

bool flag[2];      // 表示进入临界区意愿的数组
flag[0] = false;
flag[1] = false;   // 刚开始设置为两个进程都不想进入临界区# p0进程
while (flag[1]);   (1)
flag[0] = true;    (2)
critical section;  (3)
flag[0] = false;   (4)
remainder section;  # p1进程
while (flag[0]);   (5) // 如果此时P0想进入临界区,P1就一直循环等待
flag[1] = true;    (6) // 标记为P1进程想要进入临界区
critical section   (7) // 访问临界区
flag[1] = false;   (8) // 访问完临界区,修改标记为P1不想使用临界区
remainder section;

分析一下P1P_1P1​进程,如果P1P_1P1​进程想要访问临界区,首先需要知道P0P_0P0​是否想要进入临界区,只有当flag[0]为False时P1P_1P1​程序才能跳出循环;当P1P_1P1​进程确定了其它进程确实不想访问临界区之后,P1P_1P1​会把自己是否想要进入临界区的标志位设置为True,向其它进程表明P1P_1P1​进程想要访问临界区,当访问临界区之后,P1P_1P1​进程将自己的标志位设置为False,告诉其它进程当前进程已经用完临界区;

但是该方法有一个问题,上述两个进程是并发执行的,并发执行会存在一个很大的问题——异步性;如果P0P_0P0​和P1P_1P1​在执行过程中发生了切换,刚开始是进程P0P_0P0​在处理机上运行,首先运行代码语句(1),因为刚开始两个进程进入临界区的意愿都为False,刚开始执行(1)会发现P1P_1P1​进程暂时不想进入临界区,则进程P0P_0P0​会执行代码语句flag[0]=True,恰好在这个阶段发生进程切换,切换到进程P1P_1P1​,P1P_1P1​进处理机执行语句(5),此时进程P1P_1P1​发现0号进程其flag[0]为False,因此P1P_1P1​进程顺利跳出循环往下执行;

若按照(1)(5)(2)(6)(3)(7)的顺序执行,则P0P_0P0​和P1P_1P1​有可能同时访问临界区;因此,双标志监察法的主要问题是:违反“忙则等待”原则;当一个进程在访问临界区时,另一个进程也可能在访问临界区;

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

为了解决两个进程不能互斥的问题,提出了“双标志后检查法”;

4、双标志后检查法

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

其代码如下所示:

bool flag[2];
flag[0] = False;
flag[1] = False;# P0进程
flag[0] = true;    (1)
while (flag[1]);   (2)
critical section;  (3)
flag[0] = false;   (4)
remaider section;# P1进程
flag[1] = true;    (5)  // 标记为P1进程想要进入临界区
while(flag[0]);    (6)  // 如果P0也想进入临界区,则P1循环等待;
critical section;  (7)  // 访问临界区;
flag[1] = false;   (8)  // 访问完临界区,修改标记为P1不想使用临界区;
remaider section;

但是上述方法同样存在问题,若按照(1)(5)(2)(6)…的顺序执行,则P0P_0P0​和P1P_1P1​都无法进入临界区;

因此,双标志后检验法虽然解决了“忙则等待”的问题,但是又违背了“空闲让进”和“有限等待”的原则,会因各进程都长期无法访问临界资源而产生“饥饿”现象;两个进程都争着想进入临界区,但是谁也不让谁,最后谁都无法进入临界区;

5、Peterson算法

算法思想:双标志后检查法中,两个进程都争着想进入临界区,但是谁也不让谁,最后谁都无法进入临界区。Gary L.Peterson想到了一种方法,如果双方都争着想进入临界区,那可以让进程尝试“孔融让梨”,主动让对方先使用临界区;

其代码如下所示:

bool flag[2];
int turn = 0;# P0  进程
flag[0] = true;                  (1)
turn = 1;                        (2)
while (flag[1] && turn==1);      (3)
critical section;                (4)
flag[0] = false;                 (5)
remainder section;# P1 进程:
flag[1] = true;                  (6)  // 表示自己想进入临界区
turn = 0;                        (7)  // 可以优先让对方进入临界区
while (flag[0] && turn==0);      (8)  // 对方想进,且最后一次是自己让梨,那自己就循环等待
critical section;                (9)  //
flag[1] = false;                 (10) // 访问完临界区,表示自己已经不想访问临界区了
remainder section;

两种双标志法的问题都是由于进入区的几个操作不能一气呵成导致的。我们可以推理验证在Peterson算法中,两个进程进入区中的各种操作按不同的顺序穿插执行会发生什么情况:

  • 按(1)(2)(3)(6)(7)(8)…执行,执行过程类似于串行的过程,P0P_0P0​优先进入临界区;
  • 按(1)(6)(2)(3)…执行,P0P_0P0​和P1P_1P1​都表示自己想进入临界区;切换回P0P_0P0​进程,P0P_0P0​进程会表示自己愿意优先把进入临界区的权力让给P1P_1P1​进程,也就是设置turn=1;P0P_0P0​继续往下执行,因为flag[1]=true同时目前turn==1,因此P0P_0P0​会陷入while循环直到时间片用完;接着时间片分配给进程P1P_1P1​,执行turn=0和while循环,进程P1P_1P1​会陷入循环,当时间片用完切换到P0P_0P0​进程,此时因为turn=0,所以P0P_0P0​进程会跳出while循环,执行下面的语句;

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

王道 —— 进程互斥的软件实现方法相关推荐

  1. 王道操作系统考研笔记——2.3.2 进程互斥的软件实现方法

    文章目录 2.3.2 进程互斥的软件实现方法 2.3.2.1 单标志法 2.3.2.2 双标志先检查法 2.3.2.3 双标志后检查法 2.3.2.4 Peterson算法 2.3.2.5 小结 2. ...

  2. 操作系统(十九)进程互斥的软件实现方法

    2.3.2 进程互斥的软件实现方法 目录 2.3.2 进程互斥的软件实现方法 2.3.2.1 单标志法 2.3.2.2 双标志先检查法 2.3.2.3 双标志后检查法 2.3.2.4 Peterson ...

  3. 2.3.2. 进程互斥的软件实现方法

    2.3.2. 进程互斥的软件实现方法 文章目录 2.3.2. 进程互斥的软件实现方法 1.知识总览 2.单标志法 3.双标志先检查法 4.双标志后检查法 5. perterson算法 6. 知识回顾 ...

  4. 操作系统之进程管理:8、进程互斥的软件实现方法(单标志、双标志、Peterson)

    8.进程互斥的软件实现方法 思维导图 引言 1.单标志法 2.双标志法 双标志先 双标志后检查法 3.Peterson算法 思维导图 引言 上图中,进程AB同时访问打印机资源,这样就可能将AB的打印内 ...

  5. 十三、进程互斥的软件实现方法

    一.知识总览 二.单标志法 **1.算法思想:**两个进程在访问完临界区后会把使用临界区的权限转交给另一个进程,也就是说每个进程进入临界区的权限只能被另一个进程赋予. **单标志法所存在的问题:**只 ...

  6. 进程互斥的软件实现方法

    单标志法 双标志检查法 双标志后检查法 Peterson算法 Peterson算法用软件方法解决了进程互斥问题,遵循了空闲让进.忙则等待.有限等待三个原则,但是依然未遵循让权等待的原则. Peters ...

  7. 2.3.2 操作系统之实现临界区进程互斥的软件实现方法

    文章目录 0.思维导图 1.单标志法 2.双标志先检查法 3,双标志后检查法 4.Peterson算法 0.思维导图 软件实现方法的思想:在进入区设置并检查一些标志 来标明是否有进程在临界区中,若已有 ...

  8. 操作系统-进程互斥的软件实现方法

    单标志法 关于单标志法实现逻辑如下代码所示,非常简单,p0进程必须turn为0才可以进入临界区,p1则是1才可进入临界区.虽然实现了互斥,但是p0如果拿到了处理机却不执行临界区代码,则就违背了空闲让进 ...

  9. 2.3.2 进程互斥的软件实现方法

    目录 思维导图 单标志法 双标志先检查法 双标志后检查法 Peterson算法 思维导图 单标志法 critical section 临界区 exit section 退出区 remainder se ...

最新文章

  1. win10怎么设置开机启动项目_开机启动项怎么设置呢?禁用自启动程序
  2. [UVa10296]Jogging Trails
  3. java并发编程之美-阅读记录4
  4. clang编译c语言,clang没有编译c程序?
  5. java pdf 首页 缩略图_Java中将上传的文件首页生成缩略图(先将上传的文件转成pdf,然后将pdf转成jpg)...
  6. java程序优化快捷键_Java 代码中针对性能优化的总结方案
  7. HTML的SEO(搜索引擎优化)标准
  8. 单链表的插入操作的实现(0952)SUWST-OJ
  9. Java操作某方法时报错:java.lang.NoSuchMethodError
  10. 牛客网暑期ACM多校训练营(第三场): E. Sort String(KMP)
  11. 对称加密算法和非对称加密算法介绍
  12. End Game----OO最后一次博客作业
  13. 在python语言中、写文件的操作是_Python语言之详解文件操作
  14. three.js 凹凸贴图
  15. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java社区闲置物品交易平台z10mc
  16. Excel手机号如何查询实名认证?
  17. Requests: 1, Fetched: 0, Skipped: 0, Processed: 0
  18. Android 仿微信聊天气泡
  19. 整型家族(字符、短整型、整型、长整型)的范围
  20. 动手学深度学习-pytorch 导入d2lzh_pytorch模块时报错 No moudel named 'd2lzh_pytorch'

热门文章

  1. 在网上搜到的有用的资料
  2. .Text 支持二级域名之二
  3. RadonDB - 部署教程
  4. Javascript实现导出word - jquery jquery.wordexport.js 实现导出word
  5. Spring MVC国际化(i18n)和本地化(L10n)示例
  6. OpenJDK-11的新特征
  7. 如何在CentOS 7上安装和配置MySQL Cluster
  8. oracle一个lun多大,Oracle RAC中验证LUN_ID对应情况
  9. 【C#学习之旅】一、数据类型
  10. 排序算法理解总结篇——冒泡排序、选择排序、插入排序、希尔排序、归并排序、堆排序、计数排序、基数排序、桶排序