【操作系统-24】双标志先检查

双标志先检查法(Two-Flag Algorithm)

定义:

双标志先检查法(Two-Flag Algorithm)是一种解决进程互斥的算法,它是基于两个共享变量(标志)来保证两个进程之间的互斥访问。与单标志法相比,双标志法通过使用两个标志变量来避免单一标志法中的忙等待问题,并进一步提高互斥的效率和公平性。

原理:

双标志法的核心思想是使用两个共享标志(通常是 flag0 和 flag1),每个进程都有一个标志位,用来指示该进程是否准备进入临界区。当一个进程希望进入临界区时,它首先将自己的标志设置为 true,然后检查另一个进程的标志。如果另一个进程也希望进入临界区,它必须等待。双标志法通过双重检查机制,确保只有一个进程能够进入临界区。

双标记先检查法 (Double Flag, Check First):

A 标志 flag[0] ,B 标志 flag[1]

  • **核心思想:**先看对方想不想进,我再决定自己想不想进
  • 逻辑流程(以进程A为例) :
    1. while(flag1==1); // 先检查对方是否在临界区或想进入临界区
    2. flag0=true;// 确认对方不在,自己再举手
    3. 访问临界区...
    4. flag0=false;// 访问完毕,放下手
  • 缺点: 违背"忙则等待"原则。
    1. 如果A检查完 flag1为false 后,发生进程切换;
    2. B也检查完 flag0为false,接着切换回来。
    3. A设置 flag0=true 进入,B设置flag1=true进入。
    4. 两者会同时进入临界区,互斥失败。

双标志先检查法(Two-Flag Algorithm)

  • **核心思想:**我先举手表示想进,然后再看对方想不想进。如果对方也想进,我就等一下
  • 逻辑流程(以进程A为例):
    1. flag0=true;// 先举手,表示我想进
    2. while(flag1 == true);// 再检查对方是否也举手了
    3. 访问临界区...
    4. flag0=false;// 访问完毕,放下手
  • **缺点:**违背"空闲让进" 和 "有限等待" 原则,可能导致死锁(饥饿)。如果A和B几乎同时执行了第1步(都举手了),然后互相在第2步检查对方,发现对方都举手了,于是双方都在死循环里等待对方先放下手,导致谁也无法进入临界区。

双标志先检查法的操作步骤:

假设有两个进程 A 和 B,它们共享两个标志位 flag[A] 和 flag[B],初始值均为 false。

进程 A 请求进入临界区:

  1. 先检查 :进程 A 首先检查进程 B 的标志 flag[B]。

  2. 判断:

    • 如果 flag[B] 为 false(表示 B 不想进入临界区),则 A 继续下一步。

    • 如果 flag[B] 为 true(表示 B 正在或想要进入临界区),则 A 必须一直循环等待 (忙等),直到 flag[B] 变为 false。

  3. 后修改 :当确认 flag[B] 为 false 后,A 将自己的标志 flag[A] 设置为 true,表示自己现在要进入临界区。

  4. 进入:A 进入临界区执行代码。

进程 B 请求进入临界区:

  1. 先检查 :同样地,进程 B 首先检查进程 A 的标志 flag[A]。

  2. 判断:

    • 如果 flag[A] 为 false,则 B 继续下一步。

    • 如果 flag[A] 为 true,则 B 必须一直循环等待 ,直到 flag[A] 变为 false。

  3. 后修改 :当确认 flag[A] 为 false 后,B 将自己的标志 flag[B] 设置为 true。

  4. 进入:B 进入临界区执行代码。

3. 离开临界区(释放):

  1. 进程完成临界区任务后,将自己的标志位设置为 false(例如 A 将 flag[A] 设为 false)。

  2. 这表示它已释放临界区,允许另一个进程(B)检查到 false 后进入。

双标记先检查法伪代码示例:

复制代码
// 进程 A 的代码
while (true) {
    // 1. 先检查对方是否想进
    while (flag[B] == true); 
    
    // 2. 确认对方不想进后,再修改自己的标志
    flag[A] = true;          
    
    // 3. 访问临界区
    critical_section();
    
    // 4. 退出区:释放锁
    flag[A] = false;         
    
    // 5. 剩余区
    remainder_section();
}

(同理,进程 B 的代码只需将上述代码中的 A 和 B 互换即可)

双标记法的工作原理:

  • 设置两个标志变量 flag[A] 和 flag[B],初始值均为 false。用于表示两个进程是否想要进入临界区。

  • 进程在进入临界区之前,必须先检查 另一个进程的标志状态。只有当另一个进程的标志为 false(不想进入)时,当前进程才能继续。

  • 确认对方不想进入后,当前进程将自己的标志设置为 true,然后进入临界区。

  • 进程离开临界区时,将自己的标志设置为 false,允许另一个进程进入。

双标记法的优势:

避免忙等待:

  • 与单标志法相比,双标志法能有效减少忙等待。通过检查两个标志,进程能够在必要时进行等待,从而提高效率。

避免竞态条件:

  • 双标志法避免了竞态条件,即多个进程同时访问共享资源时产生的冲突,因为它保证在任何时刻只有一个进程可以进入临界区。

公平性:

  • 双标志法通过两次检查确保了公平性。两个进程都在检查对方的标志,并以此决定是否进入临界区,从而避免了进程饥饿(starvation)问题。

双标记法的缺点:

忙等待问题:

  • 双标志法仍然存在忙等待的问题。当一个进程等待时,它会不断检查标志变量的状态,浪费 CPU 时间,尤其是在进程数量多、临界区访问时间较长时,这种方式可能导致系统效率低下。

不能扩展到多个进程:

  • 双标志法设计时是为两个进程而设计的。如果需要多个进程共享资源,双标志法无法直接扩展,必须使用更复杂的同步机制(如信号量、互斥锁等)。

缺乏内存和时间的优化:

  • 双标志法需要两个共享标志变量,这在某些场景下可能不是最优的解决方案,尤其是当系统资源有限时。

双标记先检查法的改进:

增加时间限制或让进程睡眠:

  • 为了避免忙等待带来的性能问题,可以在双标志法中引入时间限制或让进程在等待时进入睡眠状态,减少不必要的 CPU 占用。

采用信号量或互斥锁:

  • 在多进程或多线程环境中,使用信号量(semaphore)或互斥锁(mutex)来代替双标志法,能够更高效地管理资源的访问,并且避免忙等待、进程饥饿等问题。

总结

双标志先检查法试图通过两个标志位来控制两个进程的互斥。它虽然改善了单标志法必须轮流执行的限制,但由于检查和修改标志位的操作无法保证原子性,它违背了"忙则等待"原则,存在严重的竞态条件,无法真正实现进程互斥。此外,它依然存在忙等待的缺陷,且仅适用于进程较少的简单场景。在现代复杂的操作系统中,通常会选择更高级的同步机制(如信号量、互斥锁等)来实现进程同步。

相关推荐
华允物联-HUAIOT1 小时前
带隔离的串口服务器有必要买吗?隔离作用对比
服务器·物联网
xiaoye-duck1 小时前
《Linux 网络编程》深入理解五种 IO 模型:从 IO 本质到非阻塞 IO 实战
linux·网络
程序员-Benothing1 小时前
Linux内核与模块管理:uname、lsmod、modprobe、sysct
linux·运维·数据库
微三云生态系统架构师-彭丹1 小时前
智慧物业工单智能派单算法:技能匹配与位置负载均衡设计
运维·负载均衡·物业管理·调度算法·工单系统·智能派单·智慧物业
嵌入式小能手1 小时前
飞凌嵌入式ElfBoard-Shell编程应用实例-使用WiFi拨号上网
linux·服务器·网络
..Dauntless..1 小时前
【Linux】环境变量
linux·运维·服务器
FED_AF2 小时前
Linux运维“邪修”功法之正则表达式
linux·运维·正则表达式
极光通讯2 小时前
服务器CPU现货选型:Intel Xeon Scalable vs AMD EPYC平台适配指南
运维·服务器
szxinmai主板定制专家2 小时前
FPGA高速IO+RK182X AI算力|RK3576+CODESYS工业自动化运动控制平台设计
运维·人工智能·嵌入式硬件·fpga开发·自动化·zynq