当前位置: 首页 > news >正文

进程互斥的硬件实现方法

本文----------------------基于B站王道计算机教育《操作系统》课程编写(类似笔记hh),部分图片来源于课程。 

一、核心思想

硬件方法通过​​原子性指令​​解决竞态条件,其本质是利用CPU底层指令的不可中断特性实现临界区保护。典型方案包括:

  • ​中断屏蔽法​​(适用于单处理器)

  • ​TestAndSet(TSL)指令​

  • ​Swap(XCHG)指令​


二、硬件实现方法

1. 中断屏蔽方法

​实现原理​​:

  • 利用“开 /关中断指令”实现
    • 关中断 即不允许当前进程被中断也必然不会发生进程切换
    • 临界区
    • 开中断 直到当前进程访问完临界区,再执行开中断指令,才有可能有别的进程上处理机并访问临界区
// 临界区保护模板
disable_interrupts(); // 关中断
// 临界区代码
enable_interrupts();  // 开中断

优点:实现简单、性能高效

缺点

  • 不适用于多处理器系统

  • 用户态进程禁止直接操作(需内核权限)

  • 长临界区会导致系统响应延迟


2. TestAndSet(TSL)指令---->不满足“让权等待”原则

也被称为测试并设置(Test-and-Set)指令 。以 C 语言描述其逻辑如下:首先,将一个存储器字读到一个寄存器中,然后在该内存地址上存一个非零值 。这个读数和写数的操作是不可分割的,即该指令结束之前其他处理机均不允许访问该存储器字 。简单来说,TSL指令会将共享变量lock的值读取到寄存器中,并将lock设置为1(表示上锁) 。若读取到的lock原始值为0,说明锁未被占用,当前线程可以获取锁;若为1,则说明锁已被占用,线程需要继续循环执行TSL指令,直到读取到的值为0 。

​原子操作流程---->不可被中断​​:

TSL REGISTER, LOCK
// 伪代码实现
bool TestAndSet(bool *lock) {bool oldValue = *lock;*lock = true;return oldValue;
}

​典型应用​​:

bool lock = false;void enter_critical() {while (TestAndSet(&lock)) {// 自旋等待}// 临界区
}void exit_critical() {lock = false;
}

优点

  • 硬件级原子性保障

  • 适用于单/多处理器环境

缺点

  • 忙等待导致CPU资源浪费

  • 未实现"让权等待"原则


3. Swap(XCHG)指令--->不满足“让权等待”原则

即交换(Exchange 或 XCHG)指令 。它是一种硬件级别的原子操作,用于交换两个内存位置的值 。在实现互斥锁时,一个内存位置通常是锁变量,另一个内存位置是一个临时变量 。其工作原理是,读取两个内存位置的值并进行交换 。如果锁变量在交换前为false(表示锁未被占用),则当前进程或线程将锁变量设置为true(通过交换操作),并进入临界区;如果锁变量在交换前为true(表示锁已被占用),则当前进程或线程将保持等待状态,直到锁变量被其他进程或线程释放(即设置为false) 。

​原子交换操作​​:

XCHG REG, MEM
// 伪代码实现
void Swap(bool *a, bool *b) {bool temp = *a;*a = *b;*b = temp;
}

​实现逻辑​​:

bool lock = false;
bool old = true;void enter_critical() {while (old == true) {Swap(&lock, &old);}// 临界区
}void exit_critical() {lock = false;
}

​对比​​:

都是先记录下此时临界区是否已经被上锁(old变量),再将上锁标记 lock 设置为 true,最后检查old,如果 old 为 false 则说明之前没有别的进程对临界区上锁,则可跳出循环,进入临界区

指令

原子性保障

忙等待问题

适用场景

TSL

✔️

单处理器实时系统

Swap/XCHG

✔️

简单并发控制


三、核心原则

方法

空闲让进

忙则等待

有限等待

让权等待

中断屏蔽

✔️

✔️

TSL指令

✔️

✔️

Swap指令

✔️

✔️

​结论​​:

硬件方法虽解决了竞态条件,但均未实现"让权等待",需结合高级同步机制(如信号量)优化


四、总结

http://www.lryc.cn/news/623491.html

相关文章:

  • 影刀初级B级考试大题2
  • 快速掌握Hardhat与Solidity智能合约开发
  • 模型提取的相关经验
  • JavaWeb前端(HTML,CSS具体案例)
  • C语言网络编程TCP通信实战:客户端↔服务器双向键盘互动全流程解析
  • Java线程的6种状态和JVM状态打印
  • Vue深入组件:Props 详解3
  • 2.Pod理论
  • Golang database/sql 包深度解析(二):连接池实现原理
  • 云原生俱乐部-RH134知识点总结(3)
  • PyCharm与前沿技术集成指南:AI开发、云原生与大数据实战
  • Spring Boot 项目配置 MySQL SSL 加密访问
  • Debug马拉松:崩溃Bug的终极挑战
  • 本地处理不上传!隐私安全的PDF转换解决方案
  • 华为云之Linux系统安装部署Tomcat服务器
  • Git 命令指南:从 0 到熟练、从常用到“几乎全集”(含常见报错与解决)建议收藏!!!
  • LintCode第137-克隆图
  • 学习游戏制作记录(玩家掉落系统,删除物品功能和独特物品)8.17
  • 《设计模式》工厂方法模式
  • 代码随想录算法训练营四十四天|图论part02
  • 天地图开发的优点
  • The Network Link Layer: 无线传感器中Delay Tolerant Networks – DTNs 延迟容忍网络
  • GANs生成对抗网络生成手写数字的Pytorch实现
  • VS Code配置MinGW64编译Apache Arrow C++库
  • 【k8s、docker】Headless Service(无头服务)
  • python+flask后端开发~项目实战 | 博客问答项目--模块化文件架构的基础搭建
  • C++算法题目分享:二叉搜索树相关的习题
  • 【前端基础】flex布局中使用`justify-content`后,最后一行的布局问题
  • ubuntu 24.04 安装
  • Android RxJava线程调度与性能优化指南