linux内核原理-原子变量,自旋锁,互斥锁/信号量
1.原子变量针对数值类型基础的算术运算提供的一种保证运算原子性机制(1). 要求a. 必须针对atomic_t类型b. 必须采用提供的原子方法实现基础算术运算原子性(2). 原理typedef struct{volatile int counter;}atomic_t;通过volatile使得每次访问counter必须访问内存以atomic_add为例说明linux内核如何保证原子操作原子性通过lock修饰汇编指令lock使得其后的一条内存访问汇编指令在执行时以原子方式不可分割的执行完成#ifdef CONFIG_SMP#define LOCK lock ; #else#define LOCK #endifstatic __inline__ void atomic_add(int i, atomic_t *v){__asm__ __volatile__(LOCKaddl %1,%0:m(v-counter):ir(i),m(v-counter));}2.自旋锁自旋锁用于保护临界区即同时只应该被一个访问者访问的区域其特性是当某个访问者申请锁时若申请不到此访问者以自旋方式等待访问者会100%占据cpu持续检测typedef struct{volatile unsigned int lock;#ifdef CONFIG_DEBUG_SPINLOCKunsigned magic;#endif#ifdef CONFIG_PREEMPTunsigned int break_lock;#endif}spinlock_t;(1). 定义与初始化#define SPINLOCK_MAGIC 0xdead4ead#ifdef CONFIG_DEBUG_SPINLOCK#define SPINLOCK_MAGIC_INIT , SPINLOCK_MAGIC#else#define SPINLOCK_MAGIC_INIT /* */#endif#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 SPINLOCK_MAGIC_INIT }#define DEFINE_SPINLOCK(x) spinlock_t x SPIN_LOCK_UNLOCKED通过DEFINE_SPINLOCK(test);定义了一个名字为test的自旋锁并对其执行了初始化(2). 加锁#define _spin_lock(lock) \do{\preempt_disable();\_raw_spin_lock(lock);\__acquire(lock);\}while(0)#define spin_lock(lock) _spin_lock(lock)通过spin_lock(test);可以申请对test加锁preempt_disable();的作用是在中断返回时禁止执行重新调度来避免当前进程被切换掉我们分析_raw_spin_lock(lock);#define spin_lock_string \\n1:\t\lock ; decb %0\n\t\jns 3f\n\2:\t\rep;nop\n\t\cmpb$0,%0\n\t\jle 2b\n\t\jmp 1b\n\3:\n\tstatic inline void _raw_spin_lock(spinlock_t *lock){__asm__ __volatile__(spin_lock_string:m(lock-lock)::memory);}上述获取锁的逻辑是a. 原子的递减lock-lock这使得内存中此变量减少1b. 分析上一步结果若未产生负数这意味着我们已经成功获取了锁继续执行若产生负数这意味着之前存在至少一个使用者已经获取了这个锁且未释放进入cc. 循环迭代空操作读取lock-lock实时值和0比较若小于等于0继续循环迭代若大于0这对应锁的使用者释放了锁跳到a因为多核下可能多个等待着此时同时感知此情况因此需让它们接下来都执行a首个执行成功者获得锁后续执行者将再次回到c中循环迭代的等待逻辑__acquire(lock);其实是一个空操作(3). 释放锁#define spin_unlock(lock) _spin_unlock(lock)通过spin_unlock(test);可以释放test#define _spin_unlock(lock) \do{\_raw_spin_unlock(lock);\preempt_enable();\__release(lock);\}while(0)我们分析_raw_spin_unlock(lock);#define spin_unlock_string \movb$1,%0\:m(lock-lock)::memorystatic inline void _raw_spin_unlock(spinlock_t *lock){__asm__ __volatile__(spin_unlock_string);}释放锁的过程是将数值1直接设置到lock-lock的过程在x86体系下单独的读一次内存写一次内存汇编操作无需lock修饰也是原子的(4).尝试加锁通过一个原子交换汇编指令即可若此前未被加锁则获得锁同时设置了lock-lock为0若此前已被加锁再次为其设置为0也无错3.互斥锁互斥锁用于保护临界区即同时只应该被一个访问者访问的区域其特性是当某个访问者申请锁时若申请不到此访问者以阻塞方式等待主动放弃cpu待条件满足时由另一角色执行唤醒任务互斥锁在实现上可认为特殊的信号量当某个信号量的初始资源数量为1时此信号量就是互斥锁(1). 定义与初始化#define MUTEX_DEFAULT 0x0struct semaphore{raw_spinlock_t lock;unsigned int count;struct list_head wait_list;};typedef struct semaphore mutex_t;mutex_t test;即可定义一个名为test的互斥锁#define __SEMAPHORE_INITIALIZER(name, n) \{\.lock__RAW_SPIN_LOCK_UNLOCKED((name).lock),\.countn,\.wait_listLIST_HEAD_INIT((name).wait_list),\}static inline void sema_init(struct semaphore *sem, int val){static struct lock_class_key __key;*sem(struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);lockdep_init_map(sem-lock.dep_map,semaphore-lock,__key,0);}#define mutex_init(lock, type, name) sema_init(lock, 1)通过mutex_init(test, MUTEX_DEFAULT, test);即可完成test初始化(2). 申请锁#define mutex_lock(lock, num) down(lock)通过mutex_lock(test, 1)即可执行加锁申请void __sched down(struct semaphore *sem){unsigned long flags;might_sleep();raw_spin_lock_irqsave(sem-lock, flags);if(likely(sem-count0))sem-count--;else__down(sem);raw_spin_unlock_irqrestore(sem-lock, flags);}上述过程可描述为a. 申请内部自旋互斥锁以便互斥访问临界区b. 若sem-count大于0则递减释放锁这时我们已经完成互斥锁的申请c. 若sem-count小于等于0意味着此时无法得到锁__down内部会将当前线程作为一个等待对象放在此互斥锁的等待着链表上然后设置自身状态为TASK_UNINTERRUPTIBLE并主动放弃调度后续锁的使用者执行释放时若释放后sem-count大于0会检测是否存在等待者存在则对其中一个等待着执行唤醒所以上述在立即得到锁时继续运行在暂时无法得到锁时阻塞自身放弃调度直到后续被唤醒得到锁再继续(3). 释放锁#define mutex_unlock(lock) up(lock)通过mutex_unlock(test)即可释放锁void __sched up(struct semaphore *sem){unsigned long flags;raw_spin_lock_irqsave(sem-lock, flags);if(likely(list_empty(sem-wait_list)))sem-count;else__up(sem);raw_spin_unlock_irqrestore(sem-lock, flags);}上述过程为a. 获取内部自旋锁以便互斥访问临界区b. 若无人等待递增sem-count即可完成释放c. 若存在等待者唤醒一个static noinline void __sched __up(struct semaphore *sem){struct semaphore_waiter *waiterlist_first_entry(sem-wait_list, struct semaphore_waiter, list);list_del(waiter-list);waiter-uptrue;wake_up_process(waiter-task);}(4). 尝试加锁int __sched down_trylock(struct semaphore *sem){unsigned long flags;int count;raw_spin_lock_irqsave(sem-lock, flags);countsem-count -1;if(likely(count0))sem-countcount;raw_spin_unlock_irqrestore(sem-lock, flags);return(count0);}很好解释先看能否得到锁得不到也立即返回

相关新闻

NS-USBLoader 完整上手指南:Switch 游戏传输、RCM 注入与文件拆并的实操路线图

NS-USBLoader 完整上手指南:Switch 游戏传输、RCM 注入与文件拆并的实操路线图

NS-USBLoader 完整上手指南:Switch 游戏传输、RCM 注入与文件拆并的实操路线图 【免费下载链接】ns-usbloader Awoo Installer and GoldLeaf uploader of the NSPs (and other files), RCM payload injector, application for split/merge files. 项目地址: https…

2026/8/19 15:31:49 阅读更多 →
B语言标准库libb完全指南:char、printf、printn等核心函数详解

B语言标准库libb完全指南:char、printf、printn等核心函数详解

B语言标准库libb完全指南:char、printf、printn等核心函数详解 【免费下载链接】b Compiler for the B Programming Language implemented in Crust 项目地址: https://gitcode.com/gh_mirrors/b8/b B语言(B Programming Language)是由…

2026/8/19 16:15:42 阅读更多 →
Stripe超70亿美元收购OpenRouter:支付巨头押注AI模型调用基础设施

Stripe超70亿美元收购OpenRouter:支付巨头押注AI模型调用基础设施

Stripe超70亿美元收购OpenRouter,3个月估值涨5倍美国当地时间8月16日,支付巨头Stripe以超过70亿美元的价格收购了热门路由平台OpenRouter。今年5月,OpenRouter刚完成1.13亿美元B轮融资,估值约13亿美元,不到三个月&…

2026/8/19 16:29:35 阅读更多 →

最新新闻

告别刺眼原生界面,一劳永逸的 foobar2000 美化方案:foobox-cn 皮肤上手体验

告别刺眼原生界面,一劳永逸的 foobar2000 美化方案:foobox-cn 皮肤上手体验

告别刺眼原生界面,一劳永逸的 foobar2000 美化方案:foobox-cn 皮肤上手体验 【免费下载链接】foobox-cn DUI 配置 for foobar2000 项目地址: https://gitcode.com/GitHub_Trending/fo/foobox-cn 深夜十一点,房间的灯已经关了&#xff…

2026/8/19 19:50:15 阅读更多 →
从零搭建自己的DNF私服:一条docker run命令搞定容器化服务器部署

从零搭建自己的DNF私服:一条docker run命令搞定容器化服务器部署

从零搭建自己的DNF私服:一条docker run命令搞定容器化服务器部署 【免费下载链接】dnf 项目地址: https://gitcode.com/gh_mirrors/dnf/dnf 项目名称: gh_mirrors/dnf/dnf。它做什么: 把地下城与勇士(DNF)的整…

2026/8/19 19:50:15 阅读更多 →
被黑客偷走300G机密数据,这家服务上百家政府机构的云巨头,为何“沉默”了两个月?

被黑客偷走300G机密数据,这家服务上百家政府机构的云巨头,为何“沉默”了两个月?

最新内容 微 信 搜索 公 众 号 网 络 研 究 观最近,欧洲网络安全界就发生了一起令人汗颜的“大地震”:意大利云计算与电信服务巨头 Retelit 遭到了顶级勒索软件团伙 Qilin 的猛烈攻击。高达 300 GB 的内部敏感文件被彻底外泄,包含 27 万份机密…

2026/8/19 19:50:15 阅读更多 →
马斯克又“闷声发大财”?SpaceX最新财报公布:靠卖网和搞AI,季度巨赚560亿!

马斯克又“闷声发大财”?SpaceX最新财报公布:靠卖网和搞AI,季度巨赚560亿!

最新内容 微 信 搜索 公 众 号 网 络 研 究 观提到马斯克和他的 SpaceX,很多人脑海里浮现的第一画面,或许还是航天基地里那枚冲天而起的巨大火箭,或者是人类征服火星的壮丽构想。但如果你以为 SpaceX 还只是一个单纯“烧钱放烟花”的硬核航天…

2026/8/19 19:50:15 阅读更多 →
如何轻松搞定机器人仿真录制与回放:一份完整实战指南

如何轻松搞定机器人仿真录制与回放:一份完整实战指南

如何轻松搞定机器人仿真录制与回放:一份完整实战指南 【免费下载链接】IsaacLab Unified framework for robot learning built on NVIDIA Isaac Sim 项目地址: https://gitcode.com/GitHub_Trending/is/IsaacLab 凌晨两点,你终于按下了训练脚本的…

2026/8/19 19:50:14 阅读更多 →
TabSTAR NPU适配踩坑实录:GELU精度偏差与erf补丁修复全过程

TabSTAR NPU适配踩坑实录:GELU精度偏差与erf补丁修复全过程

TabSTAR NPU适配踩坑实录:GELU精度偏差与erf补丁修复全过程 【免费下载链接】tabstar-npu 项目地址: https://ai.gitcode.com/atlasleong/tabstar-npu 把 TabSTAR 这款融合文本描述与数值特征的表格基础模型(tabular foundation model&#xff0…

2026/8/19 19:49:14 阅读更多 →

日新闻

【单片机课程设计/毕业设计】基于 STM32 与 WiFi 模块的室内通风智能管控系统设计 基于 STM32 的人体存在感知自适应风扇控制系统设计(018503)

【单片机课程设计/毕业设计】基于 STM32 与 WiFi 模块的室内通风智能管控系统设计 基于 STM32 的人体存在感知自适应风扇控制系统设计(018503)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/8/19 0:00:30 阅读更多 →
AI如何驱动数学猜想生成:从大语言模型到自动化数学发现

AI如何驱动数学猜想生成:从大语言模型到自动化数学发现

1. 项目概述:当AI开始“猜”数学定理 最近在AI研究圈里,一个名为“Moonshine”的项目引起了不小的讨论。这名字本身就挺有意思,直译是“月光”,但在数学史上,它特指一个神秘而美丽的联系——魔群月光猜想,连…

2026/8/19 0:00:30 阅读更多 →
WarcraftHelper 魔兽争霸3优化实战指南

WarcraftHelper 魔兽争霸3优化实战指南

WarcraftHelper 魔兽争霸3优化实战指南 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 一台刚配的新电脑,跑《魔兽争霸3》却卡成 PPT——这…

2026/8/19 0:02:31 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/19 11:55:18 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/19 9:46:27 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/19 11:55:16 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/19 5:04:55 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/19 7:42:22 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/19 11:55:13 阅读更多 →