新闻详情

新闻详情

首页 / 资讯中心 / 详情

驱动中的并发与竞争

发布时间:2026/9/8 15:19:06来源:尧图网络
驱动中的并发与竞争
1. 原子操作原子整形操作typedef struct { int counter; } atomic_t; atomic_t b ATOMIC_INIT(0); //定义并初始化 /* 常用操作函数 */ void atomic_set(atomic_t *v, int i); // 设置值为i int atomic_read(atomic_t *v); // 读取当前值 void atomic_add(int i, atomic_t *v); // 增加i void atomic_sub(int i, atomic_t *v); // 减少i void atomic_inc(atomic_t *v); // 自增1 void atomic_dec(atomic_t *v); // 自减1 int atomic_dec_and_test(atomic_t *v); // 自减并测试是否为0原子位操作—— 位操作为内存操作不依赖于 atomic_t 类型/* 直接在内存地址上操作 */ void set_bit(int nr, volatile unsigned long *addr); // 将addr的第nr位置1 void clear_bit(int nr, volatile unsigned long *addr); // 将addr的第nr位清0 void change_bit(int nr, volatile unsigned long *addr);// 翻转addr的第nr位 int test_bit(int nr, volatile unsigned long *addr); // 测试addr的第nr位 int test_and_set_bit(int nr, volatile unsigned long *addr); // 测试并置位 int test_and_clear_bit(int nr, volatile unsigned long *addr); // 测试并清零2. 自旋锁进程与进程间当使用临界区资源的时候如果资源被其他进程A的自旋锁锁住那么另一个进程B在访问该资源的时候便会不断的查询资源是否被释放因此进程B不会进入休眠而是会随着时间片不断地运行这样会浪费处理器的时间因此自旋锁应用于短时间的轻量级加锁如果需要长时间持有锁则不能用自旋锁。在单核SOC芯片中自旋锁的使用会导致抢占式调度被关闭。因此如果在使用自旋锁的过程中使用了阻塞的代码使得进程进入休眠例如任务A在获取锁后调用阻塞函数进入休眠虽然使用自旋锁会关闭抢占式调度导致调度器无法进行任务切换但主动让出schedule是允许的此时CPU切换到任务B而任务B中也尝试获取锁但因为任务A还没有释放锁因此导致任务B不断查询资源当时间片到达之后由于抢占式调度被关闭调度器无法重新执行任务ACPU一直执行任务B出现死锁。进程与中断间进程中使用锁的时候先关闭中断释放锁后打开中断有相应的函数能够保存中断状态。自旋锁适合在中断中使用因为使用互斥体的进程在申请访问临界资源的时候如果没有申请到则会进入休眠状态释放CPU去执行其他的任务但是由于中断上下文Interrupt Context不是进程它不依赖task_struct因此不能睡眠也不能被调度。这意味着释放CPU之后无法再次回到中断执行剩下的任务导致逻辑混乱。中断下半部Tasklet/Workqueue中锁的使用陷阱1Tasklet 中的自旋锁Tasklet 运行在软中断上下文可被硬件中断抢占且同一个 Tasklet 不会同时在多个 CPU 上运行但不同 Tasklet 可能并行。/* Tasklet 使用自旋锁 —— 必须使用 spin_lock_bh() 版本 */ void tasklet_handler(unsigned long data) { spin_lock_bh(lock); /* 禁止下半部软中断的抢占 */ /* 临界区访问 */ spin_unlock_bh(lock); }陷阱1Tasklet 中如果使用spin_lock_irqsave()会错误地关闭所有硬件中断导致中断响应延迟增大。spin_lock_bh()只关闭软中断包括 Tasklet 和 Timer保留硬件中断响应这更适合下半部场景。陷阱2Tasklet 中绝对不能使用互斥体mutex或信号量semaphore的睡眠版本因为软中断上下文不支持调度。2Workqueue 中的锁使用Workqueue 运行在进程上下文内核线程可以睡眠。/* Workqueue 中使用互斥体 —— 推荐 */ struct mutex lock; void work_handler(struct work_struct *work) { mutex_lock(lock); /* 可能睡眠适合长时间临界区 */ /* 临界区访问 */ mutex_unlock(lock); }陷阱Workqueue 虽然可以睡眠但如果使用自旋锁仍需注意不能在持有自旋锁时调用任何可能睡眠的函数如kmalloc(GFP_KERNEL)、copy_from_user()等否则会触发内核警告甚至系统崩溃。对比总结下半部机制上下文类型推荐锁机制禁止操作Tasklet软中断上下文自旋锁spin_lock_bh睡眠、mutexWorkqueue进程上下文互斥体/信号量持有自旋锁时睡眠/* 示例代码 47.3.2.1 自旋锁使用示例 */ DEFINE_SPINLOCK(lock); /* 定义并初始化一个锁 */ /* 线程 A */ void functionA () { unsigned long flags; /* 中断状态 */ spin_lock_irqsave(lock, flags); /* 获取锁保存中断状态 */ /* 临界区 */ spin_unlock_irqrestore(lock, flags); /* 释放锁恢复中断状态 */ } /* 中断服务函数上半部 */ void irq_handler() { spin_lock(lock); /* 获取锁已在中断上下文无需关中断 */ /* 临界区 */ spin_unlock(lock); /* 释放锁 */ }3. 信号量计数信号量可以控制同一时间访问资源的任务的数量允许多个任务同时访问但数量受限于初始计数值。二值信号量要么0要么1同一时间只能有一个任务访问类似于互斥锁。但信号量不要求持有者释放即一个任务可以 down() 而另一个任务可以 up()这一点与互斥体不同。/* Linux 内核信号量使用示例 */ struct semaphore sem; sema_init(sem, 5); /* 计数信号量初始值5允许5个任务同时访问 */ sema_init(sem, 1); /* 二值信号量初始值1 */ void task_entry() { down(sem); /* 获取信号量可被信号打断 */ // down_interruptible(sem); /* 可被信号中断的版本推荐使用 */ /* 临界区访问 */ up(sem); /* 释放信号量 */ }信号量 vs 互斥体信号量适用于进程上下文且允许在中断上下文释放up而互斥体只能在进程上下文使用且要求获取和释放必须在同一上下文。4. 互斥体相当于值为1的信号量二值信号量但互斥体更严格语义更清晰明确用于互斥访问支持优先级继承以解决优先级反转问题。使用限制只能在进程上下文使用不能用于中断且获取和释放必须在同一进程上下文不能在一个进程获取另一个进程释放。DEFINE_MUTEX(mutex); /* 定义并初始化互斥体 */ void task_a() { mutex_lock(mutex); /* 获取互斥体不可被信号中断会一直等待 */ // mutex_lock_interruptible(mutex); /* 可被信号中断推荐在驱动中使用 */ /* 临界区 */ mutex_unlock(mutex); /* 释放互斥体 */ }锁机制选择总结锁机制上下文限制是否可睡眠适用场景原子操作任意上下文否简单的计数值修改、标志位翻转自旋锁任意上下文否短临界区特别是中断上下文中信号量进程上下文可释放于中断是多资源计数控制或进程间同步互斥体进程上下文是长临界区、互斥访问有优先级继承需求RCU任意上下文否读多写极少的场景
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

python数据与变量 2026/9/8 15:55:12

python数据与变量

1. 内置基本数据类型python中已经集成好了一些数据(无需导入),数据类型有很多:基本数据类型、容器类型、对象类型。基本数据类型是“不可再拆的最小单元”,容器类型是用来装基本类型的。(1)数值型:数字整数…

阅读更多 →
ROS机器人-从零开始每日日志记录day11 2026/9/8 15:55:12

ROS机器人-从零开始每日日志记录day11

本周一直在加班,项目能不能如期交付还是个问题...... 本周值得积累和深挖的问题有两个,记录下来方便日后翻阅,也希望能帮到同样在 ROS 路上摸索的朋友。问题一:~/.colcon/defaults.yaml 是什么文件?一句话概括这是 col…

阅读更多 →
Open GeoSpatial Engine:2014—2020年湖北省Landsat-8气溶胶AOD产品 2026/9/8 15:55:12

Open GeoSpatial Engine:2014—2020年湖北省Landsat-8气溶胶AOD产品

湖北省Landsat-8气溶胶AOD产品:2014—2020年大气环境定量遥感数据免费开放 数据集简介 湖北省Landsat-8气溶胶AOD定量遥感产品(LC08_L1TP_Hubei1420_AOD) 是由开放地球引擎(Open GeoSpatial Engine, OGE) 平台发布的…

阅读更多 →
IAR跨平台IDE实测:Linux下嵌入式开发与工程迁移指南 2026/9/8 15:55:12

IAR跨平台IDE实测:Linux下嵌入式开发与工程迁移指南

最近IAR Embedded Workbench推出了原生跨平台IDE,Linux和Windows都能跑了。我第一时间装了Linux版实测,这篇文章就把新版特性、安装配置、工程迁移和踩坑记录都整理出来,给准备切换环境或者想在Linux下做嵌入式的朋友做个参考。先说结论&…

阅读更多 →
2026项目管理工具选型:开放平台能力决定一切 2026/9/8 15:55:12

2026项目管理工具选型:开放平台能力决定一切

每次聊到团队换项目管理工具,我的第一反应已经从“任务好不好用”变成了“开放平台行不行”。这句话放在两三年前还会让人觉得想太多,但在2026年,这已经是再现实不过的选型标准——尤其当你的团队已经离不开自动化、跨系统同步、AI助手自动拆…

阅读更多 →
PyTorch 文档构建实战:autosummary 类引用页模板 class.rst 的逐行解析 2026/9/8 15:52:12

PyTorch 文档构建实战:autosummary 类引用页模板 class.rst 的逐行解析

PyTorch 文档构建实战:autosummary 类引用页模板 class.rst 的逐行解析 【免费下载链接】pytorch Tensors and Dynamic neural networks in Python with strong GPU acceleration 项目地址: https://gitcode.com/GitHub_Trending/py/pytorch 本文以 PyTorch …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞