🔥 推荐:《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.pswp.cn/news/910042.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/910042.shtml
英文地址,请注明出处:http://en.pswp.cn/news/910042.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

效果成本双突破!快手提出端到端生成式推荐系统OneRec!

近日,快手推荐模型团队提出了一个端到端生成式推荐系统OneRec,该系统采用Encoder-Decoder架构,引入了基于奖励机制的偏好对齐方法,借助强化学习增强模型效果,可在奖励模型引导下直接生成契合用户偏好的视频内容。通过极…

flex布局 项目属性

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>flex布局 项目属性</title> <link href"css/k.css" rel"stylesheet" /> </head> <bod…

SpringBoot扩展——应用Web Service!

应用Web Service Web Service是一个SOA&#xff08;面向服务的编程&#xff09;架构&#xff0c;这种架构不依赖于语言&#xff0c;不依赖于平台&#xff0c;可以在不同的语言之间相互调用&#xff0c;通过Internet实现基于HTTP的网络应用间的交互调用。Web Service是一个可以…

EasyExcel学习笔记

EasyExcel学习 一、EasyExcel简介 一、EasyExcel是什么 EasyExcel是一个基于Java的简单、省内存的读写Excel的阿里开源项目。在尽可能节约内存的情况下支持读写百M的Excel。 官网&#xff1a;https://easyexcel.opensource.alibaba.com/ 学习Easyexcel前需要了解导入和导出…

day4课程

1整体认识和路由配置 2二级分类面包屑导航实现 3基础商品列表渲染 4列表筛选功能实现 5列表无限加载功能实现 6定制路由滚动行为 7详情页整体认识和路由配置 8详情页基础数据渲染 9详情页基础组件封装和数据渲染 10适配不同title和数据列表 11小图切换大图 12滑块跟随鼠标移动 …

kubeadm worker节点加入master失败

文章目录 1、操作2、问题现象3、问题原因4、问题解决4.1、重新生成token4.2、重新生成hash值 5、验证 1、操作 执行以下命令&#xff0c;让worker节点加入到master节点 kubeadm join 103.123.222.241:6443 --token vxe3v1.wzpnks8v1vbbtsu0 --discovery-token-ca-cert-hash s…

二十二、【用户管理与权限 - 篇四】后端权限定义:模型与 API 实现

【用户管理与权限 - 篇四】后端权限定义:模型与 API 实现 前言准备工作第一部分:设计并创建 `Permission` 模型第二部分:更新 `Role` 模型以关联 `Permission`第三部分:生成并应用数据库迁移第四部分:创建 Serializers第五部分:创建 ViewSets第六部分:注册 API 路由第七…

猜数字小游戏微信流量主小程序开源

这个智力小游戏采用了数字华容道的玩法&#xff0c;玩家需要通过移动数字方块&#xff0c;将数字按顺序排列完成游戏。代码严格遵循微信小程序的目录结构&#xff0c;包含以下部分&#xff1a; 完整的小程序配置文件&#xff08;app.js、app.json、app.wxss&#xff09; 游戏页…

探秘阿里云EBS存储:云计算的存储基石

一、引言 在云计算时代&#xff0c;数据如同企业的生命线&#xff0c;数据存储的重要性不言而喻。随着企业数字化转型的加速&#xff0c;海量数据的存储与高效管理成为亟待解决的问题。云存储以其卓越的灵活性、可扩展性和成本效益&#xff0c;逐渐成为众多企业的首选方案。在…

音视频之H.264的可伸缩编码SVC

系列文章&#xff1a; 1、音视频之视频压缩技术及数字视频综述 2、音视频之视频压缩编码的基本原理 3、音视频之H.264/AVC编码器原理 4、音视频之H.264的句法和语义 5、音视频之H.264/AVC解码器的原理和实现 6、音视频之H.264视频编码传输及其在移动通信中的应用 7、音视…

Anaconda安装env,yml一直卡在Solving environment:不动

如果在使用conda env creat -f env.yml时候&#xff0c;anaconda一直卡住&#xff0c;如下 可以尝试下面操作。 conda config --set solver libmamba # 使用libmamba引擎&#xff08;Conda≥22.11&#xff09; conda env create -f env.yaml # 重新尝试

榕壹云婚恋相亲系统:ThinkPHP+UniApp打造高效婚配平台

引言 在数字化浪潮下,婚恋相亲行业正加速向线上迁移。榕壹云公司基于市场需求与技术积累,开发一款功能完备、技术开源的婚恋相亲小程序系统,为单身人士提供高效、安全的婚恋平台。本文将围绕系统背景、客户定位、核心技术、功能模块及优势场景展开详细解析,助力开发者与技…

查询docker-compose 部署的milvus 请求日志

在 Docker Compose 部署的 Milvus 中,日志默认存储在各个服务的容器内。以下是定位和查询日志的方法: 1. 查看实时日志 使用 docker-compose logs 命令查看实时日志: bash # 查看所有服务的日志 docker-compose logs -f# 仅查看 Milvus 服务日志(服务名以 docker-compos…

Rsync实操

Rsync实操 一.rsync命令 #类似于cp[rootuser2 ~]# rsync info.sh root192.168.168.130:/rootroot192.168.168.130s password: [rootuser1 ~]# lsanaconda-ks.cfg ceph-release-1-1.el7.noarch.rpm info.sh 二、使用rsync备份push方式 服务器&#xff1a;server 192.168.168…

Java常见八股-(6.算法+实施篇)

Java常见八股-&#xff08;1.Java基础篇&#xff09; Java常见八股-&#xff08;2.Java高级篇&#xff09; Java常见八股-&#xff08;3.MySQL篇&#xff09; Java常见八股-&#xff08;4.前端篇&#xff09; Java常见八股-&#xff08;5.框架篇&#xff09; 目录 一、算…

阿里云部署的SMTP服务器安全攻防实录:深度解析攻击、防护与加固

阿里云部署的SMTP服务器安全攻防实录&#xff1a;深度解析攻击、防护与加固 一次针对云上SMTP服务的持续攻击事件&#xff0c;揭示了邮件中继服务面临的多重安全挑战。本文将深入剖析攻击手法、防护策略与系统性加固方案。 某企业在阿里云上部署的Postfix SMTP服务器近期遭遇…

HTTP与HTTPS深度解析:从明文传输到安全通信的演进之路

引言 在互联网的早期&#xff0c;HTTP&#xff08;超文本传输协议&#xff09;作为Web通信的基石&#xff0c;凭借简单高效的特性推动了万维网的爆发式增长。但随着互联网从“信息共享”向“价值交互”演进&#xff0c;HTTP的明文传输特性逐渐暴露致命缺陷——用户的每一次点击…

渗透实战:绕过沙箱机制的反射型XSS

Lab 24&#xff1a;利用 xss 绕过 csrf 防御 依然是留言板的问题可以执行<h1>标签 进入修改邮箱的界面&#xff0c;修改抓包 这里构造修改邮箱的代码 <script> var req new XMLHttpRequest(); req.onload handleResponse; req.open(get,/my-account,true); req…

K8S篇之利用deployment实现滚动平滑升级

一、更新策略 在 Kubernetes (K8s) 中,滚动平滑升级(Rolling Update)是一种无缝更新部署的方式,允许你在不中断服务的情况下逐步更新应用程序。这是 Kubernetes 默认的 Deployment 更新策略,它会按照指定的步幅逐步替换 Pods,确保在新版本的应用程序没有完全替换旧版本的…

【Dify 案例】【MCP实战】【一】【前置配置】

MCP(Model Context Protocol,模型上下文协议) ,2024年11月底,由Anthropic 推出的一种开放标准。旨在为大语言模型(LLM)提供统一的、标准化方式与外部数据源和工具之间进行通信。 MCP 作为一种标准化协议,极大地简化了大语言模型与外部世界的交互方式,使开发者能够以统…