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

Linux 内核同步管理全解:原理 + 实战 + 考点


🔥 推荐:《Yocto项目实战教程:高效定制嵌入式Linux系统》
京东正版促销,欢迎支持原创!
链接:https://item.jd.com/15020438.html




一、为什么需要同步机制?

Linux 是一个支持 多核并发 + 抢占式调度 的操作系统,多个内核线程可能同时访问同一份内存区域,例如:驱动共享某个全局变量、文件系统缓存读写、网络缓冲区处理等等。

如果没有同步机制,就会产生竞态条件(Race Condition),导致数据错乱、内核崩溃甚至安全漏洞。

因此,Linux 内核实现了一整套高效的同步机制,用来协调不同 CPU、不同执行上下文之间对共享资源的访问。


二、Linux 中的主要同步机制

同步机制是否可睡眠适用场景常见用法内核位置
原子变量简单计数/标志状态标志、自增自减include/linux/atomic.h
自旋锁中断处理、短临界区硬件寄存器、短时间保护include/linux/spinlock.h
信号量多资源管理限制并发访问数include/linux/semaphore.h
互斥锁临界区保护普通数据结构保护include/linux/mutex.h
RCU部分读者无锁读多写少的表结构任务列表、网络表项kernel/rcu/

三、五种同步机制逐一讲解

3.1 原子变量

✅ 场景:状态标志、自增计数器
atomic_t count;
atomic_set(&count, 0);atomic_inc(&count);  // ++count
atomic_dec(&count);  // --countif (atomic_read(&count) == 0) {// 说明资源清空或条件满足
}
  • 原子变量适合简短逻辑,如计数器、标志位。
  • 不适合保护复杂数据结构。
✅ 面试考点:
  • 原子变量是否需要锁?→ 否。
  • 原子操作能否用于中断上下文?→ 可以。

3.2 自旋锁(Spinlock)

✅ 场景:短时间保护、中断上下文
spinlock_t my_lock;
spin_lock_init(&my_lock);spin_lock(&my_lock);
/* 访问共享资源 */
spin_unlock(&my_lock);

在这里插入图片描述


🔥 推荐:《Yocto项目实战教程:高效定制嵌入式Linux系统》
京东正版促销,欢迎支持原创!
链接:https://item.jd.com/15020438.html



✅ 中断安全版本:
unsigned long flags;
spin_lock_irqsave(&my_lock, flags);
/* 临界区 */
spin_unlock_irqrestore(&my_lock, flags);
✅ 特点:
  • 获取不到锁会 原地忙等(自旋),适合快速操作;
  • 不可用于睡眠上下文,否则死锁;
  • 常用于中断处理函数、底半部等高优先级逻辑。
✅ 面试考点:
  • spin_lock 与 mutex 有什么区别?
  • 中断上下文是否可以使用 mutex?→ 否。

3.3 信号量(Semaphore)

✅ 场景:控制多个线程对有限资源访问
struct semaphore sem;
sema_init(&sem, 3);  // 最多允许3个并发/* 请求资源 */
down(&sem);  // 若资源不足,将睡眠/* 使用资源 *//* 释放资源 */
up(&sem);
  • 适合表示资源池,如“3台打印机”、“10个缓存槽位”;
  • 已逐渐被 mutex 替代。
✅ 面试考点:
  • down()/up() 会阻塞线程吗?→ 是。
  • 信号量适合中断中使用吗?→ 否(会睡眠)。

3.4 互斥锁(Mutex)

✅ 场景:线程间对共享数据的互斥访问
struct mutex my_mutex;
mutex_init(&my_mutex);mutex_lock(&my_mutex);
/* 临界区代码 */
mutex_unlock(&my_mutex);
  • 获取不到锁会让当前线程 挂起等待,资源释放后再调度回来;
  • 不适合中断处理。
✅ 特点对比:
比较项spinlockmutex
可否睡眠
场景中断/底半部普通线程
获取失败自旋等待睡眠等待
✅ 面试考点:
  • mutex 和 semaphore 区别?→ semaphore 是计数,mutex 仅一人。

3.5 RCU(Read-Copy-Update)

✅ 场景:读多写少,如任务列表、网络表项
读操作(不加锁):
rcu_read_lock();
my_ptr = rcu_dereference(global_ptr);
/* 安全读取数据 */
rcu_read_unlock();
写操作(复制更新):
new_ptr = kmalloc(...);
/* 修改副本 */
rcu_assign_pointer(global_ptr, new_ptr);
synchronize_rcu();
/* 释放旧数据 */
kfree(old_ptr);
✅ 特点:
  • 读性能极高,不加锁;
  • 写复杂,需注意数据生命周期;
  • 常用于链表、哈希表等结构。
✅ 面试考点:
  • RCU 是否支持多读多写?→ 多读 + 单写 + 延迟销毁。
  • RCU 与普通锁最大区别?→ 读时不阻塞。

四、实战示例:共享计数器保护

❌ 错误示例:未加锁

static int count = 0;void do_work(void) {count++;  // 多线程访问存在竞态!
}

✅ 正确方式:使用原子变量

static atomic_t count = ATOMIC_INIT(0);void do_work(void) {atomic_inc(&count);
}

✅ 或使用自旋锁

static int count = 0;
static spinlock_t lock;void do_work(void) {spin_lock(&lock);count++;spin_unlock(&lock);
}

✅ 或使用 mutex(若可睡眠)

static int count = 0;
static struct mutex my_mutex;void do_work(void) {mutex_lock(&my_mutex);count++;mutex_unlock(&my_mutex);
}

五、面试常见问题汇总(含答案)

  1. spinlock 和 mutex 有何区别?

    • spinlock 不可睡眠、适用于中断上下文;mutex 会睡眠、适合线程间同步。
  2. 原子变量需要加锁吗?

    • 不需要,已具备原子性。
  3. 哪些锁不能用于中断?

    • mutex、semaphore 会睡眠,不能用于中断处理。
  4. RCU 为什么性能高?

    • 读操作无锁,不阻塞任何线程,极高并发性。
  5. 如何避免死锁?

    • 保持锁获取顺序一致;禁止在持锁时调用睡眠函数(如 mutex + msleep());中断上下文避免调用可睡眠接口。

六、小结:如何选用同步机制?

场景建议同步方式
标志位、计数器原子变量
中断处理、底半部自旋锁
用户进程临界区互斥锁 mutex
限制访问数量(N个资源)信号量 semaphore
读多写少表结构RCU

七、结束语

Linux 内核的同步机制是驱动开发和内核编程中的“必修课”,掌握好它不仅能写出正确的代码,更是迈入高级内核开发的关键一步。

📚 🔥 推荐:《Yocto项目实战教程:高效定制嵌入式Linux系统》
京东正版促销,欢迎支持原创!
链接:https://item.jd.com/15020438.html


🎥 视频教程请关注 B 站:“嵌入式 Jerry”

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

相关文章:

  • 第六章 进阶25 超级丹谈管理
  • servlet前后端交互
  • 在Django中把Base64字符串保存为ImageField
  • 掌握Python编程的核心能力,能快速读懂并上手项目开发。
  • HCIP-数据通信基础
  • 【网工】华为配置专题进阶篇④
  • 【Dify学习笔记】:RagFlow接入Dify基础教程
  • STM32:AS5600
  • Vuex(一) —— 集中式的状态管理仓库
  • 掌握Bash脚本编写:从服务启动脚本到语法精要
  • 防止应用调试分析IP被扫描加固实战教程
  • SAM2论文解读-既实现了视频的分割一切,又比图像的分割一切SAM更快更好
  • Springboot仿抖音app开发之Nacos 分布式服务与配置中心(进阶)
  • 文件夹美化工具推荐,打造个性化电脑界面
  • 音视频之H.264的可伸缩编码SVC
  • 【案例】性能优化在持续集成与持续交付中的应用
  • GO Gin Web框架面试题及参考答案
  • FPGA基础 -- Verilog 共享任务(task)和函数(function)
  • UE5错误 Linux离线状态下错误 请求失败libcurl错误:6无法解析主机名
  • 信任再造:跌倒检测算法如何让善意不再“自证”
  • Real-World Deep Local Motion Deblurring论文阅读
  • 结构体的嵌套问题
  • 【2025 年】软件体系结构考试试卷-期末考试
  • ABAP(2) 定义数据
  • 软件公司进军无人机领域的战略指南与生态合作全景-优雅草卓伊凡
  • Git 命令全景图:从 clone 到 merge 的完整流程解析
  • (双模第一期)从零打造蓝牙低功耗键盘——全流程详解与工具清单
  • window显示驱动开发—使用状态刷新回调函数
  • Vue2 day01
  • 20250620在Ubuntu20.04.6下编译KickPi的K7的Android14系统