zoukankan      html  css  js  c++  java
  • 进程互斥软件实现之Lamport面包店算法

    一. 进程互斥的实现方式

    1. 软件方式:

    保护临界区, 自己编写代码来实现对进程的控制.

    Dekker算法
    Peterson算法
    Lamport算法等

    2. 硬件方式:

    使用特殊指令保护临界区.

    开关中断指令
    测试并加锁指令
    交换指令
    忙等待, 自旋锁


    二. Lamport面包店算法

    解决多线程并发访问同一个共享资源的互斥问题

    这个思想来自于面包店, 医院等, 需要排队取号的场所. 顾客进入面包店前,首先抓取一个号码,然后按号码从小到大的次序依次进入面包店购买面包.

    前提:
    面包店按由小到大的次序发放号码
    两个或两个以上的顾客有可能得到相同号码
    当多个顾客抓到相同号码,则按顾客名字的字典次序排序

    基本思想:
    发号器按由小到大的次序发放号码. 进程进入临界区前先抓取一个号码, 然后按号码从小到大的次序依次进入临界区. 若多个进程抓到相同的号码则按进程编号依次进入.

    伪算法:

     1 // 变量说明:
     2 // i 表示当前进程PID
     3 // j 表示当前迭代到的进程PID
     4 // choosing[i] 表示当前进程i是否正在取号, 默认值为false
     5 // number[i] 表示当前进程i的排队号, 默认值为0
     6 
     7 process(i) {
     8     while (true) {
     9         // 当前进程i正在取号
    10         choosing[i] = true;
    11         // number为上一个已发放的排队号加1
    12         number[i] = 1 + max(number[1], number[2], ..., number[n-1]);
    13         // 当前进程i取号完毕
    14         choosing[i] = false;
    15         
    16         // 迭代所有进程
    17         for (j = 0; j < n; j++)
    18         {
    19             // 若当前迭代到的进程j正在取号, 则等待其取号完毕
    20             while(choosing[j]);
    21 
    22             // 同时满足, 当前进程才能通过
    23             while (number[j] != 0 && (number[j], j) < (number[i], i));
    24         }
    25 
    26         // 临界区代码
    27 
    28         // 当前进程注销排队号
    29         // 一旦线程在临界区执行完毕,需要把自己的排队签到号码置为0,表示处于非临界区
    30         number[i] = 0;
    31 
    32         // 其它代码
    33 
    34     }     
    35 }

    注意:
    1) 进程需要排队等待的三种情况:
    情况1: 存在没有取得排队号的进程
    情况2: 当前迭代到的进程没有取得排队号
    情况3: 当前迭代到的进程的排队号小于当前进程的排队号, 或当前迭代到的进程PID小于当前进程PID

    2) 只有当前进程注销了排队号, 在排队的其它进程才能进入临界区, 满足进程互斥和有限等待

    3) 符号说明: (a, b) < (c, d) 表示 (a < c) or ((a == c) and (b < d))

    4) 使用choosing数组是必须的, 假设不使用choosing数组, 就可能会出现这种情况: 设进程i的优先级高于进程j(即 i < j), 两个进程获得了相同的number,
    进程i在写number[i]之前, 被优先级低的进程j抢先获得了CPU时间片, 这时进程j读取到的number[i]为0, 因此进程j进入了临界区. 随后进程i又获得CPU时间片, 它读取到的number[i]与number[j]相等, 且i < j, 因此进程i也进入了临界区. 这样, 两个进程同时在临界区内访问, 可能会导致数据腐烂(data corruption). 算法使用了choosing数组变量, 使得修改number数组的元素值变得"原子化", 解决了上述问题

    后续:

    在Linux上实现编写C程序实现面包店算法

    参考:
    1. 《算法之美》—进程互斥软件算法(Lamport面包店算法和Eisenberg算法)
    https://www.xuebuyuan.com/647028.html
    2. 面包店算法 - CSDN
    https://blog.csdn.net/yucan1001/article/details/7973075

  • 相关阅读:
    UVa 116 单向TSP(多段图最短路)
    POJ 1328 Radar Installation(贪心)
    POJ 1260 Pearls
    POJ 1836 Alignment
    POJ 3267 The Cow Lexicon
    UVa 1620 懒惰的苏珊(逆序数)
    POJ 1018 Communication System(DP)
    UVa 1347 旅行
    UVa 437 巴比伦塔
    UVa 1025 城市里的间谍
  • 原文地址:https://www.cnblogs.com/shaohsiung/p/9881334.html
Copyright © 2011-2022 走看看