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

Linux内核互斥技术1

Linux内核互斥技术

在内核中,可能出现多个进程访问同一个对象、进程和硬中断访问同一个对象、多个处理器访问同一个对象等现象,我们需要使用互斥技术,确保每个时刻只有一个主体可以进入临界区访问对象

如果临界区的执行时间比较长或者可能睡眠,可使用:

  1. 信号量,大多数我们使用互斥信号量
  2. 读写信号量
  3. 互斥锁
  4. 实施互斥锁
    申请这些锁的时候,如果锁被其他进程占有,进程将会睡眠等待,代价很高

如果申请临界区的执行时间短,并且不会睡眠,那么使用上面的锁不太合适,因为进程切换代价很高,可以使用:

  1. 原子变量
  2. 自旋锁
  3. 读写自旋锁
  4. 顺序锁
    申请这些锁的时候,如果锁被其他进程占有,进程自旋等待(也称忙等待)

进程还可以使用以下技术

  1. 禁止内核抢占,防止被当前处理器上的其他进程抢占
  2. 禁止软中断,防止被当前处理器上的软中断抢占
  3. 禁止硬中断,防止被当前处理器上的硬中断抢占

避免使用锁的互斥技术

  1. 每处理器变量
  2. 每处理器计数器
  3. 内存屏障
  4. 读-复制更新
  5. 可睡眠RCU

信号量

信号量允许多个进程同时进入临界区,大多情况下只允许一个进程进入临界区,把信号量的计数值设置为1,即二值信号量,也称为互斥信号量
与自旋锁相比,信号量适合保护比较长的临界区,因为竞争信号量时进程可能睡眠被再次唤醒,代价高

struct semaphore {
	raw_spinlock_t		lock; /* 自旋锁,保护信号量其他成员 */
	unsigned int		count; /* 计数器,表示还可以允许多少进程进入临界区 */
	struct list_head	wait_list; /* 等待进入临界区的进程链表 */
};

读写信号量

struct rw_semaphore {
	atomic_long_t count;
	atomic_long_t owner;
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
	struct optimistic_spin_queue osq; /* spinner MCS lock */
#endif
	raw_spinlock_t wait_lock; /* 自旋锁,保护信号量其他成员 */
	struct list_head wait_list; /* 等待进入临界区的进程链表 */
#ifdef CONFIG_DEBUG_RWSEMS
	void *magic;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
	struct lockdep_map	dep_map;
#endif
};

互斥锁

互斥锁只允许一个进程进入临界区,适合保护比较长的临界区,因为竞争互斥锁时进程可能睡眠和再次唤醒,代价很高,尽管可以把二值信号量当作互斥锁使用

struct mutex {
	atomic_long_t		owner;
	spinlock_t		wait_lock;
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
	struct optimistic_spin_queue osq; /* Spinner MCS lock */
#endif
	struct list_head	wait_list;
#ifdef CONFIG_DEBUG_MUTEXES
	void			*magic;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
	struct lockdep_map	dep_map;
#endif
};

实时互斥锁

如果使用实时互斥锁,编译内核时需要开启配置宏CONFIG_RT_MUTEXES

struct rt_mutex {
	raw_spinlock_t		wait_lock;
	struct rb_root_cached   waiters;
	struct task_struct	*owner;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
	struct lockdep_map	dep_map;
#endif
};

原子变量

自旋锁

读写自旋锁

顺序锁

禁止内核抢占

进程和软中断互斥

进程和硬中断互斥

每处理器变量

每处理器计数器

内存屏障

RCU

可睡眠RCU

死锁检测工具

相关文章:

  • 【RHCE-第五天作业】
  • MFCC--学习笔记
  • 领航杯2022年-Crypto-rsa
  • 黄北断裂和渤南2号断裂
  • JS逆向之巨量算数signature与data解密
  • 网站收录查询-批量网站收录查询软件
  • Docker - 镜像的分层 - busybox镜像制作
  • 每日三题 9.02
  • RabbitMQ 26问,基本涵盖了面试官必问的面试题
  • 轻取软考45分之软考信息系统项目管理师范围管理​章节学习笔记
  • C#实现二叉树的最大深度
  • 用Python实现广度优先搜索
  • bitset位集学习
  • Modbus协议介绍
  • 我赢助手之引流篇:短视频私域、自有鱼塘背后的底层逻辑是什么?
  • @angular/forms 源码解析之双向绑定
  • Android优雅地处理按钮重复点击
  • Docker: 容器互访的三种方式
  • ES10 特性的完整指南
  • ES6--对象的扩展
  • Git 使用集
  • jdbc就是这么简单
  • k8s 面向应用开发者的基础命令
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • nodejs:开发并发布一个nodejs包
  • storm drpc实例
  • Vue ES6 Jade Scss Webpack Gulp
  • Vue 动态创建 component
  • Vue全家桶实现一个Web App
  • yii2中session跨域名的问题
  • 理清楚Vue的结构
  • 使用API自动生成工具优化前端工作流
  • 数组的操作
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • 译米田引理
  • 交换综合实验一
  • 移动端高清、多屏适配方案
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • ​插件化DPI在商用WIFI中的价值
  • #ifdef 的技巧用法
  • #pragma预处理命令
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (ZT)出版业改革:该死的死,该生的生
  • (第61天)多租户架构(CDB/PDB)
  • (二十三)Flask之高频面试点
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (转)jQuery 基础
  • (转)Mysql的优化设置
  • (转)一些感悟
  • (转载)PyTorch代码规范最佳实践和样式指南
  • (状压dp)uva 10817 Headmaster's Headache
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET CLR基本术语
  • .NET LINQ 通常分 Syntax Query 和Syntax Method
  • .net 反编译_.net反编译的相关问题